@_ed/grid 中文文档教程
用于 React 的易于使用、响应迅速的 n 列网格系统,使用 styled-components
集成和 TypeScript 支持构建。 支持混合使用不同分辨率的静态网格(以 px
为单位)和流体网格(以 vw
为单位)。
Installation
yarn add @_ed/grid
Usage
这个库提供了三个主要组件:
<GridProvider />
— Defines grid properties for descendant Row and Col elements.<Row />
— Creates a new row in the grid.<Col />
— Where the magic happens!
还有一些有用的混合器用于 styled-components
。
GridProvider
要开始使用该系统,您首先需要使用 createGrid()
创建一个网格定义,并将其提供给 GridProvider
组件,如下所示:
// theme.ts (or theme.js)
import { createGrid } from '@_ed/grid'
export const grid = createGrid({
columns: 12,
breakpoints: {
xs: {
at: 0,
fluid: true,
padding: 5,
gutter: 5,
width: 100
},
md: {
at: 900,
fluid: true,
padding: 2,
gutter: 3,
width: 100
},
lg: {
at: 1500,
fluid: false,
padding: 40,
gutter: 30,
width: 1200
}
}
})
上面创建了一个 12 - 列,移动优先网格,具有三个断点,分别命名为 xs
、md
和 lg
。 前两个尺寸是流动的,而 lg
断点是基于像素的。 在单独的文件中定义网格非常有用,可以减少混乱。
要在您的应用程序中使用这些网格设置:
// App.ts
import { GridProvider } from `@_ed/grid`
import { grid } from 'theme'
export function App() {
return (
<GridProvider grid={grid}>
<Row>
<Col cols={12}>
<h1>My Cool Site!</h1>
</Col>
</Row>
</GridProvider>
)
}
Row
您必须将 组件组包装在
中以确保正确的布局。
Row 目前只需要两个属性,gutterTop
和 gutterBottom
,它们都是可选的。 它们可以是 true
或数字。 使用这些道具会将 margin-top
和/或 margin-bottom
分配给当前断点的 gutter
大小的值。 这允许您在上方/下方具有与列之间相同的间距。 还有一个 mixin 可以在其他任何地方实现这一点。
Col
Col
组件采用以下属性:
cols
— (required) the number of columns this element should take up. This will be the default number of columns, but can be overridden per-breakpoint.left
— (optional, number) adds amargin-left
to this element, where the value is the number passed, multiplied by the column width, plus any gutters. This affects the placement of this column, plus any columns to the right.right
— (optional, number) adds amargin-right
to this element, where the value is the number passed, multiplied by the column width, plus any gutters. This affects any columns to the right.drift
— (optional, number) shifts the element by n columns. A negative number will drift the column to the left, and a positive to the right. This does not affect surrounding columns.visible
— (optional, defaults to true, boolean) whether or not this column is visible.
每个属性都可以被每个断点覆盖。 只需将断点名称添加到属性名称前面,驼峰式。 例外情况是使用断点名称而不是 cols
。 例如,如果你有一个 lg
断点,你可以使用 lg
, lgLeft
, lgRight
, lgDrift
,lgVisible
。
Grid Settings
网格是用 createGrid
创建的——见上面的例子。
创建网格时,每个断点可以有以下参数。
at
(required, number) — the screen resolution at which this breakpoint takes effect. For the smallest mobile breakpoint, this should be0
fluid
(required, boolean) — whether or not this breakpoint is fluid, or static in width. Static breakpoints will usepx
for all CSS, whereas fluid will usevw
for all CSS. You would typically make all of your breakpoints fluid, except for perhaps the largest one, if you'd like to limit the width of your content on a larger screen.width
(required, number) — the total width of the grid, in grid units, at this breakpoint, including all side padding, gutters and columns. For fluid, this should probably be100
. For static, it'll be in pixels (eg1200
).gutter
(required, number) — the spacing between each column, in grid units. For fluid, you might use3
(3% of the viewport width), whereas for static you might use30
(for 30px).padding
(required, number) — similar togutter
, except it instead defines the spacing between the content and the edge of the grid. You'd often set this to be the same value asgutter
columns
(optional, number) — use this to override the number of columns at this breakpoint. For instance, you might set this to4
for your mobile grid. In most cases, you'll probably want to just ignore this option.
Mixins
有一些 mixin 可用于 styled-components
。 有些甚至允许您完全绕过 Col
和 Row
:)
column(args)
采用与 Col组件,上面有详细说明。 事实上,
Col
组件只是使用了这个 mixin!
import styled from 'styled-components'
import { column } from '@_ed/grid'
const BigRedCol = styled.div`
background: red;
${column({
cols: 12,
mdCols: 6
})}
`
row()
不接受任何参数。 它添加了适当的样式来创建类似 Row 的组件。
import styled from 'styled-components'
import { row } from '@_ed/grid'
const MyCustomRow = styled.div`
margin-top: 100px;
margin-bottom: 100px;
${row()}
`
columnPadding(args, fromSize)
args 应该是一个对象,包含一个或两个参数,gutterTop
和 gutterBottom
,都是数字。 它将为每个断点添加 margin-top
或 margin-bottom
,其中使用的值是间距大小乘以提供的数字。 也有一个可选的 fromSize
参数,它应该是一个断点名称。 填充将从该断点和更大的断点开始应用。
import styled from 'styled-components'
import { columnPadding } from '@_ed/grid'
const GridItem = styled.div`
${columnPadding({
gutterTop: 2
})}
`
each(callback)
— 为每个断点调用回调,返回结果。 每个断点的结果自动包装在一个固定媒体查询中(使用min-width
和max-width
),因为结果每个断点只影响那个确切的断点(不是移动优先)。
import styled, { css } from 'styled-components'
import { each } from '@_ed/grid'
const OneColHigh = styled.div`
// Make this div the same height as 1 column width,
// for every breakpoint
${each(breakpoint => css`
height: ${breakpoint.colWidths[1]}${breakpoint.units};
`)}
`
at(sizes, callback)
— 与 each
完全相同,但是您必须指定一个或多个要迭代的大小。 就像 each
一样,每个断点的回调结果都包含在一个最小/最大媒体查询中,而不仅仅是一个 min-width
。 size
参数应该是字符串或字符串数组。 callback
也可以只是一段 CSS,而不是一个函数。
import styled, { css } from 'styled-components'
import { at } from '@_ed/grid'
const MyBox = styled.div`
// Font size is 30 on desktop, 10 on mobile
font-size: 30px;
${at('xs', css`
font-size: 10px;
`)}
// Padding-top is the same as the gutter size on xs and md
${at(['xs', 'md'], breakpoint => css`
padding-top: ${breakpoint.gutter}${breakpoint.units};
`)}
from(sizes, callback)
— 与 at
相同,只是所使用的媒体查询未被限制。 这意味着,如果您有断点 xs
、md
和 lg
,那么 from('md')
将影响md
和 lg
。
import styled, { css } from 'styled-components'
import { from } from '@_ed/grid'
const MyBox = styled.div`
// Padding-top is the same as the gutter size for `md` and higher
${from(['md'], breakpoint => css`
padding-top: ${breakpoint.gutter}${breakpoint.units};
`)}
queryAt(sizes)
— 以 (min-width: X) 和 (max-width: X)
的形式生成一个固定的媒体查询,除了最小的断点是 (max-width: X)
或最大断点 (min-width: X)
。 sizes
arg 可以是字符串或字符串数组
import styled, { css } from 'styled-components'
import { queryAt } from '@_ed/grid'
const MyBox = styled.div`
// Hide this element at the xs breakpoint only
@media ${queryAt('xs')} {
display: none;
}
queryFrom(size)
— 生成一个 min-width
媒体查询,它的内容来自指定大小及以上
import styled, { css } from 'styled-components'
import { queryFrom } from '@_ed/grid'
const MyBox = styled.div`
// Hide this element at md and higher breakpoints
@media ${queryFrom('md')} {
display: none;
}
— TODO,尚未构建!queryTo(size)
columnWidth(cols, size?)
— 将此元素的宽度设置为与具有该列数的列相同。 size
arg 是一个可选的断点名称,此 mixin 将应用于该名称。
import styled, { css } from 'styled-components'
import { columnWidth } from '@_ed/grid'
const MyBox = styled.div`
${columnWidth(6)} // default to 6
${columnWidth(8, 'lg')} // 8 cols wide at 'lg'
Grid Properties
当使用 each
或 useGrid()
方法,或从 props.theme.grid
访问网格时,您应该注意每个断点都具有通过 createGrid
传递的属性的附加属性。 这是架构:
name: string
— the name of the breakpoint, egxs
columns: number
— the number of columns at this breakpoint. defaults to the number of columns for the grid.min: number
— the minimum viewport width for this breakpointmax: number | null
— the size of the next biggest breakpoint, or null for the largestquery: string
— a string in the form(min-width: min)
, or an empty string for the smallestrangedQuery: string
— the same asquery
, but also includes a(max-width)
valuecolWidths: { [index: number]: number }
— a dictionary of column widths. SocolWidths[2]
is how wide a Col taking up 2-columns would be.units: string
— either "vw" or "px"size
— an object with all primitive sizes used by this breakpoint. It has the propertieswidth
,column
,gutter
andpadding
Tips
Mobile-First
该系统本质上是移动优先的。 当您使用 组件时,
cols
属性将针对所有 断点。 如果你有 3 个断点,sm
、md
和 lg
,那么 mdCols
属性将针对这两个 md
和 lg
断点。
Nesting Rows and Cols
行和列可以无限嵌套,但是嵌套应该在 Row
和 Col
之间交替。
例如,这将导致显示问题:
<Col cols={12}>
<Col cols={6}>
INVALID
</Col>
<Col cols={6}>
INVALID
</Col>
</Col>
相反,您应该这样做:
<Col cols={12}>
<Row>
<Col cols={6}>
:)
</Col>
<Col cols={6}>
:)
</Col>
</Row>
</Col>
An easy-to-use, responsive n-column grid system for React, built with styled-components
integration and TypeScript support. Supports a mix of static grids (in px
) and fluid grids (in vw
) at different resolutions.
Installation
yarn add @_ed/grid
Usage
This library provides three main components:
<GridProvider />
— Defines grid properties for descendant Row and Col elements.<Row />
— Creates a new row in the grid.<Col />
— Where the magic happens!
There are also a handful of useful mixins for use with styled-components
.
GridProvider
To begin using the system, you'll first need to create a grid definition using createGrid()
, and supply it to a GridProvider
component like so:
// theme.ts (or theme.js)
import { createGrid } from '@_ed/grid'
export const grid = createGrid({
columns: 12,
breakpoints: {
xs: {
at: 0,
fluid: true,
padding: 5,
gutter: 5,
width: 100
},
md: {
at: 900,
fluid: true,
padding: 2,
gutter: 3,
width: 100
},
lg: {
at: 1500,
fluid: false,
padding: 40,
gutter: 30,
width: 1200
}
}
})
The above creates a 12-column, mobile-first grid, with three breakpoints, named xs
, md
and lg
. The first two sizes are fluid, while the lg
breakpoint is pixel based. It's useful to define your grid in a separate file, to reduce clutter.
To use these grid settings in your application:
// App.ts
import { GridProvider } from `@_ed/grid`
import { grid } from 'theme'
export function App() {
return (
<GridProvider grid={grid}>
<Row>
<Col cols={12}>
<h1>My Cool Site!</h1>
</Col>
</Row>
</GridProvider>
)
}
Row
You must wrap groups of <Col />
components in a <Row />
to ensure correct layout.
Row currently only takes two props, gutterTop
and gutterBottom
, which are both optional. They can either be true
or a number. Using these props will assign margin-top
and/or margin-bottom
, to the value of the current breakpoint's gutter
size. This allows you to have the same spacing above/below, as between columns. There is also a mixin to achieve this anywhere else.
Col
The Col
component takes the following props:
cols
— (required) the number of columns this element should take up. This will be the default number of columns, but can be overridden per-breakpoint.left
— (optional, number) adds amargin-left
to this element, where the value is the number passed, multiplied by the column width, plus any gutters. This affects the placement of this column, plus any columns to the right.right
— (optional, number) adds amargin-right
to this element, where the value is the number passed, multiplied by the column width, plus any gutters. This affects any columns to the right.drift
— (optional, number) shifts the element by n columns. A negative number will drift the column to the left, and a positive to the right. This does not affect surrounding columns.visible
— (optional, defaults to true, boolean) whether or not this column is visible.
Each property can be overridden for each and any breakpoint. Simply prepend the breakpoint name, to the property name, camel-cased. The exception is that the breakpoint name is used instead of cols
. For example, if you have a lg
breakpoint, you can use lg
, lgLeft
, lgRight
, lgDrift
, lgVisible
.
Grid Settings
Grids are created with createGrid
— see the example above.
When creating a grid, each breakpoint can have the following parameters.
at
(required, number) — the screen resolution at which this breakpoint takes effect. For the smallest mobile breakpoint, this should be0
fluid
(required, boolean) — whether or not this breakpoint is fluid, or static in width. Static breakpoints will usepx
for all CSS, whereas fluid will usevw
for all CSS. You would typically make all of your breakpoints fluid, except for perhaps the largest one, if you'd like to limit the width of your content on a larger screen.width
(required, number) — the total width of the grid, in grid units, at this breakpoint, including all side padding, gutters and columns. For fluid, this should probably be100
. For static, it'll be in pixels (eg1200
).gutter
(required, number) — the spacing between each column, in grid units. For fluid, you might use3
(3% of the viewport width), whereas for static you might use30
(for 30px).padding
(required, number) — similar togutter
, except it instead defines the spacing between the content and the edge of the grid. You'd often set this to be the same value asgutter
columns
(optional, number) — use this to override the number of columns at this breakpoint. For instance, you might set this to4
for your mobile grid. In most cases, you'll probably want to just ignore this option.
Mixins
There are a handful of mixins available for use with styled-components
. Some even allow you to bypass using Col
and Row
altogether :)
column(args)
takes the same arguments as the Col
component, detailed above. In fact, the Col
component just uses this mixin!
import styled from 'styled-components'
import { column } from '@_ed/grid'
const BigRedCol = styled.div`
background: red;
${column({
cols: 12,
mdCols: 6
})}
`
row()
takes no arguments. It adds the appropriate styling to create a Row-like component.
import styled from 'styled-components'
import { row } from '@_ed/grid'
const MyCustomRow = styled.div`
margin-top: 100px;
margin-bottom: 100px;
${row()}
`
columnPadding(args, fromSize)
args should be an object, containing one or two arguments, gutterTop
and gutterBottom
, both numbers. It'll add margin-top
or margin-bottom
for each breakpoint, where the value used is the gutter size multiplied by the number supplied. Also takes an optional fromSize
argument, which should be a breakpoint name. The padding will apply from this breakpoint and larger.
import styled from 'styled-components'
import { columnPadding } from '@_ed/grid'
const GridItem = styled.div`
${columnPadding({
gutterTop: 2
})}
`
each(callback)
— calls your callback for each breakpoint, returning the result. The result for each breakpoint is automatically wrapped in a clamped media query (with min-width
AND max-width
), in that the result for each breakpoint only affects that exact breakpoint only (not mobile-first).
import styled, { css } from 'styled-components'
import { each } from '@_ed/grid'
const OneColHigh = styled.div`
// Make this div the same height as 1 column width,
// for every breakpoint
${each(breakpoint => css`
height: ${breakpoint.colWidths[1]}${breakpoint.units};
`)}
`
at(sizes, callback)
— exactly the same as each
, however you must specify one or more sizes to be iterated over. Just like each
, the result of your callback for each breakpoint is wrapped in a min/max media query, rather than just a min-width
one. The size
argument should either be a string, or an array of strings. callback
can also just be a piece of CSS, rather than a function.
import styled, { css } from 'styled-components'
import { at } from '@_ed/grid'
const MyBox = styled.div`
// Font size is 30 on desktop, 10 on mobile
font-size: 30px;
${at('xs', css`
font-size: 10px;
`)}
// Padding-top is the same as the gutter size on xs and md
${at(['xs', 'md'], breakpoint => css`
padding-top: ${breakpoint.gutter}${breakpoint.units};
`)}
from(sizes, callback)
— the same as at
, except the media queries used are not clamped. This means that if you have breakpoints xs
, md
and lg
, then from('md')
will affect both md
and lg
.
import styled, { css } from 'styled-components'
import { from } from '@_ed/grid'
const MyBox = styled.div`
// Padding-top is the same as the gutter size for `md` and higher
${from(['md'], breakpoint => css`
padding-top: ${breakpoint.gutter}${breakpoint.units};
`)}
queryAt(sizes)
— produces a clamped media query in the form (min-width: X) and (max-width: X)
, except for the smallest breakpoint which would be (max-width: X)
or the largest breakpoint which would be (min-width: X)
. The sizes
arg can be a string or array of strings
import styled, { css } from 'styled-components'
import { queryAt } from '@_ed/grid'
const MyBox = styled.div`
// Hide this element at the xs breakpoint only
@media ${queryAt('xs')} {
display: none;
}
queryFrom(size)
— produces a min-width
media query, which will it's contents from the specified size and upwards
import styled, { css } from 'styled-components'
import { queryFrom } from '@_ed/grid'
const MyBox = styled.div`
// Hide this element at md and higher breakpoints
@media ${queryFrom('md')} {
display: none;
}
— TODO, not built yet!queryTo(size)
columnWidth(cols, size?)
— sets the width of this element to be the same as a column with that number of columns. The size
arg is an optional breakpoint name, for which this mixin will apply.
import styled, { css } from 'styled-components'
import { columnWidth } from '@_ed/grid'
const MyBox = styled.div`
${columnWidth(6)} // default to 6
${columnWidth(8, 'lg')} // 8 cols wide at 'lg'
Grid Properties
When using mixins like each
, or the useGrid()
method, or when accessing the grid from props.theme.grid
, you should note that each breakpoint has additional properties to the ones passed in with createGrid
. Here is the schema:
name: string
— the name of the breakpoint, egxs
columns: number
— the number of columns at this breakpoint. defaults to the number of columns for the grid.min: number
— the minimum viewport width for this breakpointmax: number | null
— the size of the next biggest breakpoint, or null for the largestquery: string
— a string in the form(min-width: min)
, or an empty string for the smallestrangedQuery: string
— the same asquery
, but also includes a(max-width)
valuecolWidths: { [index: number]: number }
— a dictionary of column widths. SocolWidths[2]
is how wide a Col taking up 2-columns would be.units: string
— either "vw" or "px"size
— an object with all primitive sizes used by this breakpoint. It has the propertieswidth
,column
,gutter
andpadding
Tips
Mobile-First
This system is inherently mobile-first. When you use a <Col />
component, the cols
prop will target all breakpoints. If you have 3 breakpoints, sm
, md
and lg
, then the mdCols
prop will target both md
and lg
breakpoints.
Nesting Rows and Cols
Rows and columns can be nested infinitely, however the nesting should alternate between Row
and Col
.
For example, this will result in display issues:
<Col cols={12}>
<Col cols={6}>
INVALID
</Col>
<Col cols={6}>
INVALID
</Col>
</Col>
Instead you should do this:
<Col cols={12}>
<Row>
<Col cols={6}>
:)
</Col>
<Col cols={6}>
:)
</Col>
</Row>
</Col>