有几个选项可以使用最小的HTML代码;一个是使用CSS Grid,另一个是使用CSS flex-box布局。
/* A simple reset to ensure that all elements and
pseudo-elements have their margin and padding
set to zero, and all are using the same box-sizing: */
*,
::before,
::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* here we set the <form> element's layout to use
grid layout: */
form {
display: grid;
/* we use the repeat() function to create 2 columns,
each column sized with a minimum of 0 width and a
maximum of 1fr; the 'fr' unit is a fractional unit
and here forces each column to take one fractional
unit of the available space to create two equal-sized
columns: */
grid-template-columns: repeat(2, minmax(0, 1fr));
/* we use the 'gap' property (formerly 'grid-gap') to
specify the gap between grid elements; here we have
0.5em above and below and 1em to the left and right: */
gap: 0.5em 1em;
width: 80vw;
margin: 0 auto;
}
label {
/* aligning the text to the right of the <label> element: */
text-align: right;
}
label::after {
/* using the 'content' property of the pseudo-element to
add the colon character: */
content: ':'
}
<form>
<!-- using the 'for' attribute to associate the label with the
relevant <input> element; the value of the 'for' attribute
must be equal to the 'id' attribute-value of the relevant
<input> -->
<label for="input1">label</label>
<input type="text" id="input1" placeholder="input 1">
<label for="input2">A longer label</label>
<input type="text" id="input2" placeholder="input 2">
<label for="input3">Another slightly longer label</label>
<input type="text" id="input3" placeholder="input 3">
<label for="input4">A label that goes on, frankly, for quite a bit further than might be common for the average <label> element</label>
<input type="text" id="input4" placeholder="input 4">
</form>
/* A simple reset to ensure that all elements and
pseudo-elements have their margin and padding
set to zero, and all are using the same box-sizing: */
*,
::before,
::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* setting the layout of the <form> to flexbox: */
form {
display: flex;
/* allowing the child elements of the <form> to wrap
to new lines when necessary: */
flex-wrap: wrap;
width: 80vw;
margin: 0 auto;
}
/* Setting common properties for the <label> and <input>
elements: */
label,
input {
/* assigning the flex-grow and flex-shrink (respectively)
properties to 1, in order that they grow/shrink by the
same amount relative to each other; and setting the
flex-basis to 40% (the percentage derived from the parent)
in order to assign a width that's too large to accommodate
more than two elements per line: */
flex: 1 1 40%;
/* setting the margin above/below each 'row' to be 0.5em,
and 0 to the left and right: */
margin: 0.5em 0;
}
label {
text-align: right;
/* setting the margin-right of the <label> to 1em to enforce a
gutter between the <label> and the neighbouring <input> (the
CSS Box Alignment module (level 3) introduces the 'gap' property
that can also be used in the flexbox layout (among others) but
that's not yet supported by browsers, so we have to use margins: */
margin-right: 1em;
}
label::after {
content: ':'
}
<form>
<label for="input1">label</label>
<input type="text" id="input1" placeholder="input 1">
<label for="input2">A longer label</label>
<input type="text" id="input2" placeholder="input 2">
<label for="input3">Another slightly longer label</label>
<input type="text" id="input3" placeholder="input 3">
<label for="input4">A label that goes on, frankly, for quite a bit further than might be common for the average <label> element</label>
<input type="text" id="input4" placeholder="input 4">
</form>
现在,使用以上两种方法都有一个要求,可能不适合您的用例: <label>
元素必须实现一个for
属性,这要求相关的<input>
也必须有一个id
属性(并且这些值必须相等)。
为了避免这种情况,我们可以将<input>
嵌套在<label>
内部,这会自动关联<label>
和<input>
;这将产生(可能)更清晰的HTML:
*,
::before,
::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
form {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.5em 1em;
width: 80vw;
margin: 0 auto;
}
label {
/* it's a crude simplification, but effectively we remove
the <label> from the DOM and instead show its contents;
the text portion, and the <input>, become independant
grid-items (sort of): */
display: contents;
}
<form>
<label>label
<input type="text" placeholder="input 1"></label>
<label>A longer label
<input type="text" placeholder="input 2"></label>
<label>Another slightly longer label
<input type="text" placeholder="input 3"></label>
<label>A label that goes on, frankly, for quite a bit further than might be common for the average label element
<input type="text" placeholder="input 4"></label>
</form>
在上面的代码片段中,您可能会注意到以下几点:
label::after
来插入表现形式的':'
字符,因为那样显然会放置在<label>
内容之后,在<input>
之后并创建另一个网格项目(演示),<label>
文本不再右对齐;这是因为text-align
似乎不能作用于文本。*,
::before,
::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
form {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.5em 1em;
width: 80vw;
margin: 0 auto;
}
label {
display: contents;
text-align: right;
}
<form>
<label>label
<input type="text" placeholder="input 1"></label>
<label>A longer label
<input type="text" placeholder="input 2"></label>
<label>Another slightly longer label
<input type="text" placeholder="input 3"></label>
<label>A label that goes on, frankly, for quite a bit further than might be common for the average label element
<input type="text" placeholder="input 4"></label>
</form>
我们可以通过将<label>
的文本内容包装在一个元素中,比如一个<span>
来改善视觉效果,以恢复那种呈现方式:
*,
::before,
::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
form {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.5em 1em;
width: 80vw;
margin: 0 auto;
}
label {
display: contents;
text-align: right;
}
label span::after {
content: ':';
}
<form>
<label><span>label</span>
<input type="text" placeholder="input 1"></label>
<label><span>A longer label</span>
<input type="text" placeholder="input 2"></label>
<label><span>Another slightly longer label</span>
<input type="text" placeholder="input 3"></label>
<label><span>A label that goes on, frankly, for quite a bit further than might be common for the average label element</span>
<input type="text" placeholder="input 4"></label>
</form>
<input>
元素的状态来为 <label>
元素设置样式。
*,
::before,
::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
form {
display: grid;
/* to ensure that the layout backfills the empty spaces
created by moving content around: */
grid-auto-flow: dense;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.5em 1em;
width: 80vw;
margin: 0 auto;
}
label {
display: contents;
text-align: right;
}
input {
/* positioning the <input> elements in the secpond
grid-track/column: */
grid-column: 2;
}
label span {
/* positioning the <span> elements in the first
grid-track/column: */
grid-column: 1;
}
label span::after {
content: ':';
}
input:placeholder-shown+span {
color: rebeccapurple;
}
input:not(:placeholder-shown)+span {
color: limegreen;
font-weight: bold;
}
input:focus+span,
input:active+span {
color: #f90;
}
<form>
<label>
<input type="text" placeholder="input 1">
<span>label</span>
</label>
<label>
<input type="text" placeholder="input 2">
<span>A longer label</span>
</label>
<label>
<input type="text" placeholder="input 3">
<span>Another slightly longer label</span>
</label>
<label>
<input type="text" placeholder="input 4">
<span>A label that goes on, frankly, for quite a bit further than might be common for the average label element</span>
</label>
</form>
*,
::before,
::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
form {
width: 80vw;
margin: 0 auto;
}
label {
display: flex;
margin: 0.5em 0;
}
label span,
label input {
flex: 1 1 50%;
}
label span {
order: 1;
text-align: right;
margin-right: 1em;
}
label input {
order: 2;
}
label span::after {
content: ':';
}
label span::after {
content: ':';
}
input:placeholder-shown+span {
color: rebeccapurple;
}
input:not(:placeholder-shown)+span {
color: limegreen;
font-weight: bold;
}
input:focus+span,
input:active+span {
color: #f90;
}
<form>
<label>
<input type="text" placeholder="input 1">
<span>label</span>
</label>
<label>
<input type="text" placeholder="input 2">
<span>A longer label</span>
</label>
<label>
<input type="text" placeholder="input 3">
<span>Another slightly longer label</span>
</label>
<label>
<input type="text" placeholder="input 4">
<span>A label that goes on, frankly, for quite a bit further than might be common for the average label element</span>
</label>
</form>
需要注意的是,grid-auto-flow: dense
以及重新排列元素的视觉呈现可能会给使用屏幕阅读器或键盘交互的Web用户带来问题。因此,虽然它可以实现一些美观效果,但值得考虑的是这种美观是否以可用性(和潜在的合法可访问性)为代价。
此外,在后面的例子中,使用嵌套的<span>
元素来允许对<label>
元素的文本内容进行样式设置(无论是出于对齐原因、添加':'
字符还是响应与<input>
元素的交互而进行样式设置),这可能会使HTML标记变得复杂而不简洁。
参考资料:
Selectors::active
。活动状态。::after
。在元素内容后插入内容。:focus
。焦点状态。:not()
。非指定选择器。:placeholder-shown
。占位符显示状态。box-sizing
。盒模型的计算方式。display
。元素的显示方式。flex
。弹性布局。flex-basis
。伸缩基准值。flex-grow
。伸缩增长因子。flex-shrink
。伸缩收缩因子。gap
。网格间距。grid-auto-flow
。自动放置方式。grid-column
。网格列位置。grid-template-columns
。定义网格列宽度。minmax()
。最小最大值限制。order
。元素的排列顺序。repeat()
。重复值。<length>
(单位)。长度单位。参考文献:
.notATable {
display:table;
list-style:none;
padding-left:0;
}
.notATable > li
{
display:table-row;
}
.notATable > li > *
{
display:table-cell;
padding:5px;
}
.notATable label {
font-weight:bold;
text-align:right;
}
.notATable label:after {
content: ':';
}
<ul class="notATable">
<li><label>Label</label><div>Value</div></li>
<li><label>Another Label</label><div>Some Value</div></li>
<li><label>A longer Label</label><div>Another Value</div></li>
<li><label>Short Label</label><div>A different Value</div></li>
<li><label>Really, Really Long Label</label><div>Last Value</div></li>
</ul>
media-queries
在移动设备上以不同的方式显示标签和值。display:grid
的浏览器。 - mattstuehlerdisplay:grid
得到了相当好的支持。我仍然避免在我的主要工作中使用它,因为我必须支持IE9,我转而使用display:table
,因为我更熟悉它。它也相当简单,得到了很好的支持,在这种情况下只有一点标签膨胀。 - Jon P这个简单吗?
。*{
padding: 5px;
margin: 0;
font-family: verdana;
}
.d-table {
display:table;
}
.m-auto{
margin:auto
}
.d-flex{
display:flex;
}
.d-flex > div{
height: auto;
display: flex;
flex-direction: column;
justify-content: space-around;
}
label{
display:block;
text-align:right;
font-weight: bold;
margin-right: 5px;
}
<div class="d-table m-auto">
<div class="d-flex">
<div>
<label>Label:</label>
<label>Another label:</label>
<label>A long label:</label>
<label>Short label:</label>
<label>Really, really long label:</label>
</div>
<div>
<p>Value</p>
<p>Some value</p>
<p>Another value</p>
<p>A different value</p>
<p>Last value</p>
</div>
</div>
</div>
display: grid
完美地完成了工作。我一直避免使用网格布局,直到支持变得更加普遍,但现在看来我们可能已经足够接近了。如果你把它作为答案,我会将其标记为被接受的答案。 - mattstuehler