表单布局和设计一直是网页设计和开发中令人头疼的一部分。 尝试过写 标签的样式,或者在所有浏览器中都居中一个
label
的人感触肯定更深。
原文链接:https://www.sitepoint.com/css-grid-web-form-layout/
在2016年,我写了一篇文章标题为 "Make Forms Fun with Flexbox"
,文中指出了如何使用 Flexbox
布局解决多种表格布局的困难。为了展示 HTML
标签顺序的一致性,label
总是跟随在一个关联域标签之后:
<div>
<input id="name" name="name" type="text" />
<label for="name">namelabel>
div>
<div>
<select id="experience" name="experience">select>
<label for="experience">experiencelabel>
div>
<div>
<input id="html" name="html" type="checkbox" />
<label for="html">HTMLlabel>
div>
然后,Flexbox
可以这样用:
label
顺序,比如,将文本输入(input)、选择框(select) 或者 textarea
移动到 label
的左边label
和 filed
还可以使用相邻的同级选择器来根据它们的字段的状态来添加样式,例如,当选中复选框时,将粗体应用到 label
上:
input:checked + label {
font-weight: bold;
}
Flexbox
来设计表单的缺点可是在表单布局中使用 Flexbox
有很多问题。 Flexbox
创建一个一维布局,一项需要折行后跟着一项, Field/label
必须放置在带有 display: flex;
的父级容器元素中,这样才能保证每一行都换行。
必须要给 label
一个固定的宽度,例如 10em
。 因为如果一个label
内文字超长,文本可能会溢出,使得重置元素宽度或者挤出旁边的表单元素,无法与其他行的元素对齐。
最后,表单通常会在网格中设计。 我们为何不试试主流浏览器支持的 CSS Grid
布局呢?
大多数 CSS Grid
文章都介绍了这些概念,而且也为旧版本的浏览器提供了优雅降级。 当布局有很多装饰性布局的时候,这种方法是很理想的——例如,定位页面内容、页眉、页脚和菜单。就算是少量的旧浏览器内展示为线性布局,页面也依然是可用的。
表单布局从功能上来说,会相对重要,因为用户如果在错误的框中输入信息会导致信息错误。所以本教程采用的是一种渐进增强的方法:
IE8 +
(不支持 Flexbox
)。CSS Grid
来实现表单布局下面的例子因为样式很少,所以直接写在了 HTML
元素上。 这种方式 BEM
不推荐,但也能保持代码可读,整洁。
我们先写一些表单的基础结构。
一个经典的 唯一的附加元素是 在设置初始字体和颜色样式之后,需要分配浮动布局: 复选框和单选按钮放置在 这种方式的表单布局适用于所有浏览器,包括 https://codepen.io/SitePoint/pen/bxVaKK 一个不认真的开发人员会认为这样就完事儿了,但是这个表单其实还有几个小问题: 网格是二维的,同时拥有行和列。 如果一个元素对它的单元来说太大,行或列还会相应地变大。布局页面或者表单,网格真是再适合不过了。 我们在设计布局的时候,肯定会需要知道列的数量,大小,以及行和列之间的间隔。 像这样: 这里定义了四个列。单位可以用任意单位或者是 1fr 等于(1fr / 3fr) * 600px = 200px 在行之间定义 旧版本浏览器可以使用 当浏览器支持 为了逐步增强现有的表格,网格代码将放置在 在大多数网格布局中都没必要这样写。 但这个示例需要重置所有的浮动内边距和外边距——需要保证这些规则只有在能使用 这个表单布局将使用三栏设计: 这个表单的布局: 外层容器和子元素的样式: 第一个 复选框和单选按钮现在可以设置在间隙1到3(1和2列) , 网格上的 最后, 下面是最后一个基于网格的表单布局: https://codepen.io/SitePoint/pen/bxVaKK 与浮动不同,在添加不同的字体、尺寸或 一般新的学习可能需要花几年才能真正实行,但是 如果你想学习另一种 HTML
表单结构应该尽量保持简洁,没有必要用 <form action="get">
<fieldset>
<legend>Your web development skillsetlegend>
<div class="formgrid">
<input id="name" name="name" type="text" />
<label for="name">namelabel>
<select id="experience" name="experience">
<option value="1">1 year or lessoption>
<option value="2">2 yearsoption>
<option value="3">3 - 4 yearsoption>
<option value="5">5 years or moreoption>
select>
<label for="experience">experiencelabel>
<input id="html" name="html" type="checkbox" />
<label for="html">HTMLlabel>
<input id="css" name="css" type="checkbox" />
<label for="css">CSSlabel>
<input id="javascript" name="javascript" type="checkbox" />
<label for="javascript">JavaScriptlabel>
<textarea id="skills" name="skills" rows="5" cols="20">textarea>
<label for="skills">other skillslabel>
<button type="submit">SUBMITbutton>
div>
fieldset>
form>
fieldset
元素浏览器是无法设置 display: grid
或者 display: flex
的, 所以需要一个外部容器 div
包裹。
表单布局浮动布局
label
,向左浮动/* 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;
}
label
前,然后向左浮动。 它们的内部宽度可以自适应(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;
}
IE8 +
CSS
间距就会需要调整label
会溢出开始使用网格
Grid
模块为了能够创建一个有行和列的布局,新增了 18 个新的 CSS
属性。
模块增加了18个新的 CSS 属性,以便创建一个有行和列的布局。 网格内的元素可以放置在任何行/列,也可以占多行或者多列,重叠其他元素,设置水平或垂直居中。 听起来和 Flexbox
很相似,但是:Flexbox
是一维的。 元素是一个挨着一个出现的,很有可能不会包裹在一个新的"行"中。 常用的案例是菜单或者图片库CSS
网格相比基于表格的布局, 会更灵活,需要更少的标签。 相比其他的 CSS
属性,网格会更加复杂一些,学起来会稍难一点,但是不需要每个属性和值都记住,可以先了解最基本的网格在元素上的使用:.container {
display: grid;
}
.container {
display: grid;
grid-template-columns: 10% 1fr 2fr 12em;
grid-gap: 0.3em 0.6em;
}
fr
。fr
在网格布局里剩余的空间内,进行比例分配。 上面的示例中第二和第三列的总共3fr
。 如果有 600 像素的水平空间可用:
2fr 等于(2fr / 3fr) * 600px = 400px0.3em
的间隙,并在列之间定义 0.6em
。.container
所有的子元素现在都属于网格的格。 默认情况下,第一个子元素将出现在第 1 行第 1 列。 第二个子元素在第 1 行,第 2 列,第 6 个在第 2 行,第 2 列。 使用 grid-template-rows
属性可以对行进行大小调整,但高度是由内容撑开的。Grid
的兼容性很好。在 Opera Mini
中不可用, 但 IE11
提供了一个较老的补充规范。在大多数情况下,兼容设置很简单:
flexbox
, floats
,inline-blocks
或者 display: table
。所有的网格属性都会被忽略。grid
时,所有的 flexbox
,floats
,inline-blocks
和 table
布局属性会被禁用。Grid
工具和资源:MDN Grid Layout
MDN 网格布局
A Complete Guide to Grid
一个完整的网格指南
Grid by Example
网格例子
Grid “fallbacks” and overrides
网格"后退"和重写
CSS Grid Playground
网格背景图
CSS Grid Garden
网格花园
Layoutit!
用它布局Firefox
和 chrome
浏览器拥有开发工具和可视化工具,支持网格布局。表单网格
@supports
声明中:/* grid layout */
@supports (display: grid) {
...
}
CSS Grid
的时候才起作用。
label
占一列.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
定义了起始和结束的网格间隙。 间隙是两个cells
之间的边际,所以三栏形式布局有四个间隙:
grid-column: 2 / 4;
在间隙 2 和 4 之间填充内容,或者说列 2 和列 3 之间。HTML
元素是 。 它占了第二列和第三列,这意味着第一列(间隙1 或者2)是空的。 因此,默认情况下,
label
标签将下降到第2行,第1列。 然而,通过设置 grid-auto-flow: dense;
; 在 container
中,浏览器将尝试填补网格中的空单元格,然后再进入一个新的行。justify-self: end
靠右对齐:input[type="checkbox"], input[type="radio"] {
grid-column: 1 / 3;
justify-self: end;
margin: 0;
}
labels
将自适应于任何一行的单元格。 所以,现在不像是在浮动布局中需要设置默认的宽度和间距:label, input[type="checkbox"] + label, input[type="radio"] + label {
width: auto;
padding: 0;
margin: 0;
}
还可以在单元格垂直方向的顶部而不是中心:
textarea + label {
align-self: start;
}
labels
时需要调整设计的情况下,布局不会因为这些小调整而打破。网格学习
CSS Grid
有很好的支持,当你使用浮动布局或者弹性布局布局很困难的时候,提供了另一种布局的可能性。 表单是一个合适的实例,写出来的 CSS
代码会很精炼。CSS
技能,Grid
应该是你的首选。