在CSS

时间:2019-02-05 00:40:13

标签: html css

全部

在HTML和CSS中创建如下所示的简单布局的最简单方法是什么:

enter image description here

具体来说-左侧为右对齐标签,右侧为左对齐值。

我不想对左列的宽度进行硬编码-应该根据最长标签的宽度来确定。

我正在寻找一种至少在语义上合理,可以与屏幕阅读器配合使用的方法(例如,屏幕阅读器应阅读标签,然后阅读值,而不是所有标签,再阅读所有值),并且不需要一堆额外的<div>元素。

这似乎是一个合理的通用布局,所以我假设有一个非常简便的方法。但是我还没有自己弄清楚。

<table>可以很好地工作,但是正如大家提醒我的那样,切勿仅将<table>用于布局。这显然不是表格数据。

谢谢!

3 个答案:

答案 0 :(得分:2)

这很简单吗?

*{
  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>

答案 1 :(得分:2)

有两个选项,使用最少的HTML;一种使用CSS Grid,另一种使用CSS flex-box布局。

CSS网格:

/* 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 &lt;label&gt; element</label>
  <input type="text" id="input4" placeholder="input 4">
</form>

JS Fiddle demo

Flexbox:

/* 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 &lt;label&gt; element</label>
  <input type="text" id="input4" placeholder="input 4">
</form>

JS Fiddle demo

现在,使用上述两种方法,都有一个可能不适合您的用例的要求:<label>元素必须实现for属性,这要求关联的{{ 1}}还必须具有<input>属性(并且这些值必须相等)。

为避免这种情况,我们可以将id嵌套在<input>内,这会自动将<label><label>关联起来;这样可以(可能)提供更干净的HTML:

网格,再次:

<input>
*,
::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;
}

JS Fiddle demo

在上面的代码段中,您可能会注意到:

  1. 我们不再使用<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>之后并创建另一个网格项目(demo),并且
  2. <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;
}

JS Fiddle demo

我们可以在视觉上进行改进,将<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: ':';
}

还值得注意的是,CSS Grid和CSS Flexbox均允许我们在浏览器中以可视方式对元素进行重新排序,而与在DOM中出现的方式有所不同。例如,这可以使我们根据关联的<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>的状态设置<label>元素的样式,

网格:

<input>
*,
::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;
}

JS Fiddle demo

Flexbox:

<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;
}

JS Fiddle demo

但是,值得注意的是,<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>以及重新排列元素的可视化表示,可能会导致使用屏幕阅读器或键盘交互功能的Web用户出现问题。因此,尽管它可以带来一些美感,但值得考虑的是,这种美感是否是以牺牲可用性(以及潜在的法律要求的可访问性)为代价的。

在后面的示例中,进一步使用嵌套的grid-auto-flow: dense元素以使<span>元素的文本内容样式化(无论是出于对齐的原因,还是添加{{1} }字符或样式,以响应与<label>元素的交互作用,这可能是不必要的潜在“干净” HTML标记的复杂化。

参考文献:

参考书目:

答案 2 :(得分:1)

要解救的CSS表:https://css-tricks.com/almanac/properties/d/display/

这些不是表,但可用于重新创建表行为。

.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>

现在,您可以使用CSS来更改标记的布局,例如,可以使用media-queries在移动设备上以不同方式显示标签和值。