css grid布局
Form layout and design is a fundamental yet frustrating part of web design and development. Ask anyone who’s ever tried to style a <select> box or align a label consistently in all browsers.
表单布局和设计是Web设计和开发的基本但令人沮丧的部分。 询问曾尝试在所有浏览器中设置<select>框样式或一致对齐标签的人。
In 2016, I wrote “Make Forms Fun with Flexbox”, which identified how several form difficulties could be solved with Flexbox. A key benefit was HTML source order consistency, with the <label> always following its associated field tag in a container:
2016年,我写了“ 使用Flexbox使表单变得有趣 ”,其中指出了使用Flexbox可以解决几种表单困难的方法。 一个关键的好处是HTML源代码顺序的一致性, <label>始终位于容器中与其关联的字段标记之后:
<div> <input id="name" name="name" type="text" /> <label for="name">name</label> </div> <div> <select id="experience" name="experience"><!-- options --></select> <label for="experience">experience</label> </div> <div> <input id="html" name="html" type="checkbox" /> <label for="html">HTML</label> </div>Flexbox could then be used to:
然后,Flexbox可用于:
reposition the label if necessary — that is, move it to the left of the field on text inputs, select boxes, and textareas 如有必要,请重新放置标签-即,将其移动到文本输入,选择框和文本区域的字段左侧 vertically align the label and field. 垂直对齐标签和字段。It also became possible to style labels based on the state of their field using adjacent sibling selectors — for example, applying bold to a label when its associated checkbox is checked:
还可以使用相邻的同级选择器根据标签字段的状态来设置标签样式-例如,在选中标签的相关复选框时将粗体应用到标签上:
input:checked + label { font-weight: bold; }Unfortunately, there are a number of problems using Flexbox for form layout. Flexbox creates a one-dimensional layout where each item follows another and wraps to a new line when necessary. Field/label pairs must be placed in container elements with display: flex; applied to guarantee each appears on a new row.
不幸的是,使用Flexbox进行表单布局存在许多问题。 Flexbox创建一维布局,其中每个项目都紧跟另一个,并在必要时换行。 字段/标签对必须放置在具有以下display: flex;内容的容器元素中display: flex; 应用于保证每个出现在新行上。
It was also necessary to define a fixed label width, such as 10em. If a long label required more room, its text would either overflow or resize the element and push the field out of alignment with others.
还必须定义固定的标签宽度,例如10em 。 如果长标签需要更多空间,则其文本可能会溢出或调整元素的大小,并使字段与其他字段不对齐。
Finally, forms are normally laid out in a grid. Shouldn’t we be using CSS Grid now that it’s fully supported in all mainstream browsers? Absolutely!
最后,通常将表格布置在网格中。 既然所有主流浏览器都已完全支持 CSS Grid,我们是否应该使用它? 绝对!
Most CSS Grid articles demonstrate the concepts and may provide graceful degradation fallbacks for older browsers. That approach is ideal when the layout is mostly decorative — for example, positioning page content, headers, footers and menus. It rarely matters when oldBrowserX shows linear blocks in an unusual order because the page content remains usable.
大多数CSS Grid文章都演示了这些概念,并可能为较旧的浏览器提供优美的降级后备。 如果布局主要是装饰性的,例如定位页面内容,页眉,页脚和菜单,则此方法是理想的。 当oldBrowserX以异常顺序显示线性块时,这几乎无关紧要,因为页面内容仍然可用。
Form layout is more critical: a misaligned label could lead the user to enter information in the wrong box. For this reason, this tutorial takes a progressive enhancement approach:
表单布局更为关键:标签未对齐可能导致用户在错误的框中输入信息。 因此,本教程采用渐进式增强方法:
An initial floated form layout will work in all browsers including IE8+ (which doesn’t support Flexbox either). It will not be perfect, but floats never were! 初始浮动表单布局将在包括IE8 +(也不支持Flexbox)在内的所有浏览器中运行。 这将不是完美的,但从未有过花车! Enhance the form layout using CSS Grid in all modern browsers. 在所有现代浏览器中使用CSS Grid增强表单布局。The examples below contain very few CSS classes, and styling is applied directly to HTML elements. That’s not the BEM way, but it is intentional to keep the code clean and understandable without distractions.
下面的示例包含很少CSS类,并且样式直接应用于HTML元素。 这不是BEM方式,但是有意使代码保持整洁和易于理解而不会造成干扰。
You could consider using similar code as the base for all forms on your site.
您可以考虑使用类似的代码作为网站上所有表单的基础。
A typical HTML form can be kept clean, since there’s no need for containing (<div>) elements around field/label pairs:
由于不需要在字段/标签对周围包含( <div> )元素,因此可以使典型HTML表单保持整洁:
<form action="get"> <fieldset> <legend>Your web development skillset</legend> <div class="formgrid"> <input id="name" name="name" type="text" /> <label for="name">name</label> <select id="experience" name="experience"> <option value="1">1 year or less</option> <option value="2">2 years</option> <option value="3">3 - 4 years</option> <option value="5">5 years or more</option> </select> <label for="experience">experience</label> <input id="html" name="html" type="checkbox" /> <label for="html">HTML</label> <input id="css" name="css" type="checkbox" /> <label for="css">CSS</label> <input id="javascript" name="javascript" type="checkbox" /> <label for="javascript">JavaScript</label> <textarea id="skills" name="skills" rows="5" cols="20"></textarea> <label for="skills">other skills</label> <button type="submit">SUBMIT</button> </div> </fieldset> </form>The only additional element is <div class="formgrid">. Browsers can’t apply display: grid or display: flex to fieldset elements. That may eventually be fixed, but an outer container is currently required.
唯一的附加元素是<div class="formgrid"> 。 浏览器无法将display: grid或display: flex应用于fieldset元素。 最终可能会解决该问题,但是当前需要一个外部容器。
After some initial font and color styling, the float layout will allocate:
进行一些初始字体和颜色样式设置后,float布局将分配:
70% of the space to fields which are floated right 正确浮动的字段的70%空间 30% of the space to labels which are floated left. 标签向左浮动的空间的30%。 /* fallback 30%/70% float layout */ input, output, textarea, select, button { clear: both; float: right; width: 70%; } label { float: left; width: 30%; text-align: right; padding: 0.25em 1em 0 0; }Checkbox and radio buttons are positioned before the label and floated left. Their intrinsic width can be used (width:auto) but a left margin of 30% is required to align correctly:
复选框和单选按钮位于标签之前,并向左浮动。 可以使用其固有宽度( width:auto ),但需要30%的左边距才能正确对齐:
button, input[type="checkbox"], input[type="radio"] { width: auto; float: left; margin: 0.5em 0.5em 0 30%; } input[type="checkbox"] + label, input[type="radio"] + label { width: auto; text-align: left; }The form layout works in all browsers including IE8+:
表单布局适用于所有浏览器,包括IE8 +:
See the Pen form grid 1: float layout by SitePoint (@SitePoint) on CodePen.
请参见Pen 表格网格1: CodePen上的SitePoint ( @SitePoint ) 浮动布局 。
A less conscientious developer would go home for the day, but this form layout has several problems:
一个不那么认真的开发人员会全天回家,但是这种表单布局存在一些问题:
the padding and margin tweaks are fragile and can look inconsistent across browsers 填充和边距调整很脆弱,在浏览器中看起来可能不一致 if longer labels or different-sized fonts are ever required, the CSS spacing will require adjustment 如果需要更长的标签或不同大小的字体,则需要调整CSS间距 the design breaks at smaller screen sizes and labels can overflow fields. 设计会在较小的屏幕尺寸时中断,标签可能会溢出字段。The Grid module adds 18 new CSS properties in order to create a layout with rows and columns. Elements within the grid can be placed in any row/column, span multiple rows and/or columns, overlap other elements, and be aligned horizontally and/or vertically. There are similarities to Flexbox, but:
网格模块添加了18个新CSS属性,以创建具有行和列的布局。 网格内的元素可以放置在任何行/列中,跨越多个行和/或列,与其他元素重叠,并且可以水平和/或垂直对齐。 与Flexbox有相似之处,但是:
Flexbox is one-dimensional. Elements come one after the other and may or may not wrap to a new “row”. Menus and photo galleries are a typical use case. Flexbox是一维的。 元素一个接一个地出现,可能包裹也可能不包裹到新的“行”中。 菜单和照相馆是典型的用例。 Grid is two-dimensional and respects both rows and columns. If an element is too big for its cell, the row and/or column will grow accordingly. Grid is ideal for page and form layout. 网格是二维的,并且尊重行和列。 如果元素对于其单元格而言太大,则行和/或列将相应地增长。 网格是页面和表单布局的理想选择。It’s possibly better to compare CSS Grid with table-based layouts, but they’re considerably more flexible and require less markup. It has a steeper learning curve than other CSS concepts, but you’re unlikely to require all the properties and the minimum is demonstrated here. The most basic grid is defined on a containing element:
将CSS Grid与基于表的布局进行比较可能更好,但是它们更加灵活并且需要更少的标记。 与其他CSS概念相比,它的学习曲线更陡峭,但是您不太可能需要所有属性,并且此处显示了最小值。 最基本的网格在包含元素上定义:
.container { display: grid; }More practically, layouts also require the number of columns, their sizes, and the gap between rows and columns. For example:
实际上,布局还需要列数,列大小以及行与列之间的间距。 例如:
.container { display: grid; grid-template-columns: 10% 1fr 2fr 12em; grid-gap: 0.3em 0.6em; }This defines four columns. Any measurement unit can be used as well as the fr fractional unit. This calculates the remaining space in a grid and distributes accordingly. The example above defines total of 3fr on columns two and three. If 600 pixels of horizontal space was available:
这定义了四列。 可以使用任何测量单位以及fr分数单位。 这将计算网格中的剩余空间并进行相应分配。 上面的3fr在第二列和第三列上定义了总计3fr 。 如果有600像素的水平空间可用:
1fr equates to (1fr / 3fr) * 600px = 200px
1fr相当于(1fr / 3fr) * 600px = 200px
2fr equates to (2fr / 3fr) * 600px = 400px
2fr等于(2fr / 3fr) * 600px 400px = 400px
A gap of 0.3em is defined between rows and 0.6em between columns.
行之间的间距为0.6em ,列之间的间距为0.3em 。
All child elements of the .container are now grid items. By default, the first child element will appear at row 1, column 1. The second in row 1, column 2, and the sixth in row 2, column 2. It’s possible to size rows using a property such as grid-template-rows, but heights will be inferred by the content.
.container所有子元素现在都是网格项。 默认情况下,第一个子元素将出现在第1行第1列,第二个出现在第1行第2列,第六个出现在第2行第2列。可以使用诸如grid-template-rows类的属性来调整行的大小,但高度将由内容推断出来。
Grid support is excellent. It’s not available in Opera Mini, but even IE11 offers an older implementation of the specification. In most cases, fallbacks are simple:
网格支持非常出色。 它在Opera Mini中不可用,但即使IE11也提供了该规范的较早实现。 在大多数情况下,后备很简单:
Older browsers can use flexbox, floats, inline-blocks, or display:table layouts. All Grid properties are ignored.
较旧的浏览器可以使用flexbox,float,inline-blocks或display:table布局。 所有网格属性都将被忽略。
When a browser supports grid, all flexbox, floats, inline-blocks and table layout properties assigned to a grid item are disabled. 当浏览器支持网格时,分配给网格项目的所有flexbox,float,inline-blocks和表布局属性都将被禁用。Grid tools and resources:
网格工具和资源:
MDN Grid Layout
MDN网格布局
A Complete Guide to Grid
网格的完整指南
Grid by Example
示例网格
Grid “fallbacks” and overrides
网格“后备”和替代
CSS Grid Playground
CSS网格游乐场
CSS Grid Garden
CSS网格花园
Layoutit!
Layoutit!
Firefox and Chrome-based browsers have excellent DevTool Grid layout and visualization tools.
Firefox和基于Chrome的浏览器具有出色的DevTool网格布局和可视化工具。
To progressively enhance the existing form, Grid code will be placed inside an @supports declaration:
为了逐步增强现有表单,将在Grid代码中放置@supports声明:
/* grid layout */ @supports (display: grid) { ... }This is rarely necessary in most grid layouts. However, this example resets all float paddings and margins — rules that must only occur when a CSS Grid is being applied.
在大多数网格布局中,这很少是必需的。 但是,此示例将重置所有浮动填充和边距,这些规则仅在应用CSS网格时才会发生。
The form layout itself will use a three-column design:
表单布局本身将使用三列设计:
In this form layout:
在此表单布局中:
standard labels appear in column one 标准标签出现在第一栏中 checkbox and radio buttons span columns one and two (but are aligned right) 复选框和单选按钮跨越第一和第二列(但右对齐) checkbox and radio labels appear in column three 复选框和单选标签出现在第三栏中 all other fields span columns two and three. 所有其他字段跨越第二和第三列。Here are the outer container and child field properties:
这是外部容器和子字段属性:
.formgrid { display: grid; grid-template-columns: 1fr 1em 2fr; grid-gap: 0.3em 0.6em; grid-auto-flow: dense; align-items: center; } input, output, textarea, select, button { grid-column: 2 / 4; width: auto; margin: 0; }grid-column defines the starting and ending grid tracks. Tracks are the edges between cells so the three-column form layout has four tracks:
grid-column定义了开始和结束的网格轨迹。 轨道是单元格之间的边缘 ,因此三列表单布局具有四个轨道:
the first track on the left-hand side of the grid before column one 第一列之前网格左侧的第一条轨迹 the track between columns one and two 第一和第二列之间的轨道 the track between columns two and three 第二列和第三列之间的轨道 the final track on the right-hand edge of the grid after column three. 第三列之后的网格右边缘上的最终轨道。grid-column: 2 / 4; positions all fields between tracks 2 and 4 — or inside columns two and three.
grid-column: 2 / 4; 将所有字段置于轨道2和4之间-或在第二列和第三列之内 。
The first HTML element is the name <input>. It spans columns two and three, which means column one (track 1 / 2) is empty on that row. By default, the name label would therefore drop to row 2, column 1. However, by setting grid-auto-flow: dense; in the container, the browser will attempt to fill empty cells earlier in the grid before progressing to a new row.
第一个HTML元素是名称<input> 。 它跨越第二列和第三列,这意味着第一行(轨道1/2)在该行上为空。 因此,默认情况下, name标签将下降到第2行第1列grid-auto-flow: dense; 在容器中,浏览器将尝试先填充网格中的空白单元格,然后再前进到新行。
Checkboxes and radio buttons can now be set to span tracks 1 to 3 (columns one and two) but align themselves to the right-hand edge using justify-self: end:
现在可以将复选框和单选按钮设置为跨越轨道1至3(第1列和第2列),但是可以使用justify-self: end将其与右边缘justify-self: end :
input[type="checkbox"], input[type="radio"] { grid-column: 1 / 3; justify-self: end; margin: 0; }Labels on the grid will handle themselves and fit into whichever row cell is empty. However, the default widths and spacing from the float layout are now unnecessary:
网格上的标签将自行处理并适合行单元格为空的情况。 但是,现在不需要浮动布局的默认宽度和间距:
label, input[type="checkbox"] + label, input[type="radio"] + label { width: auto; padding: 0; margin: 0; }Finally, <textarea> labels can be vertically positioned at the top of the cell rather than centered:
最后, <textarea>标签可以垂直放置在单元格的顶部而不是居中:
textarea + label { align-self: start; }Here’s the final grid-based form layout:
这是最终的基于网格的表单布局:
See the Pen form grid 2: grid applied by SitePoint (@SitePoint) on CodePen.
请参阅Pen 表格网格2: SitePoint( @SitePoint )在CodePen上应用的网格 。
Unlike floats, the design won’t break at small dimensions or require tweaking when different fonts, sizes or labels are added.
与浮子不同,当添加不同的字体,大小或标签时,设计不会在小尺寸时破裂或需要进行调整。
It’s taken several years to become viable, but CSS Grid is well supported and offers layout possibilities that would have been difficult with floats or flexbox. Forms are an ideal use case, and the resulting CSS is short yet robust.
可行已经花费了几年时间,但是CSS Grid得到了很好的支持,并且提供了使用float或flexbox很难实现的布局可能性。 表单是理想的用例,并且生成CSS简短而健壮。
If you’re looking to learn another CSS technique, Grid should be at the top of your list.
如果您想学习另一种CSS技术,则Grid应该位于列表的顶部。
翻译自: https://www.sitepoint.com/css-grid-web-form-layout/
css grid布局