【问题标题】:Align items in list of list对齐列表中的项目
【发布时间】:2018-04-22 10:53:03
【问题描述】:

我有一些这样的 HTML 结构:

<ul>
<li>
  <h2>Item 1</h2>
  <dl>
    <div><dt>attr1</dt><dd>value a</dd></div>
    <div><dt>attr2</dt><dd>value b</dd></div>
    <div><dt>attr3</dt><dd>value c</dd></div>
  </dl>
</li>
<li>
  <h2>Item Another One Here</h2>
  <dl>
    <div><dt>attr1</dt><dd>value x</dd></div>
    <div><dt>attr2</dt><dd>value some bit long</dd></div>
    <div><dt>attr3</dt><dd>value z</dd></div>
  </dl>
</li>
</ul>

我希望它呈现为:

---------------------------------------------------------------------
  Item 1
  attr 1: value a  attr 2: value b              attr 3: value c
---------------------------------------------------------------------
  Item Another One Here
  attr 1: value x  attr 2: value some bit long  attr 3: value z
---------------------------------------------------------------------

属性根据其内容的长度相互对齐。

我该怎么做?

我会避免将我的标记更改为&lt;table&gt;,因为它们并不是真正的表格。我曾尝试使用display: table-* 对它们进行布局,但这不适用于标题(它应该占据整行而不是一个单元格)。

【问题讨论】:

  • 老实说,我不明白为什么不愿意在这个特定的用例中使用 。你想要实现的是一个结构。
    是一个结构元素,为此目的而构建。
    的所有内容都非常适合您尝试实现的结构(尤其是列对齐)。表格名声不好,因为它们被滥用并用作样式元素,但它们仍然有目的。
  • @RobertWade OP 解释说他不想使用 &lt;table&gt; 标记,因为它不是表格数据,而且 CSS 表格没有 colspan 像真正的表格一样(全宽标题)。 CSS 网格确实提供了a viable way 来创建此布局,但迄今为止它仍然不完美。 (子网格仍在草稿规范中)同时,我们需要另外使用display: contents 来实现这一点
  • @Danield 我也不喜欢使用表格,但提供的示例非常适合它。 “只有表格数据”可以在表格中使用的概念源于放弃表格作为主要布局工具(这是一件非常好的事情),但是 W3C 表格规范没有这样说。 w3.org/TR/html401/struct/tables.html 它显然建议将样式表用于主要布局目的。这是一个漫长而古老的论点,我的评论基于提供的示例。如果 OP 展示了他在布局中实际打算使用的内容,我的看法可能会有所不同。

标签: html css alignment


【解决方案1】:

CSS Grid Layout Module 可以实现这种布局

.container {
  display: inline-grid;
  grid-column-gap: 1em;
  grid-template-columns: repeat(3,auto);
  padding: 0;
  background-color: white;
  padding-bottom: 0.5em;
  border-bottom: 2px dashed;
}

.container li, .container dl {
  display: contents;
}

h2 {
  grid-column: 1 / -1;
  font-size: inherit;
  padding: 0.5em 0 0 0;
  border-top: 2px dashed;
}


dl > div, dd, dt {
  display: inline-block;
  padding: 0;
  margin: 0;
}
dt:after {
  content: ':'
}
dd {
 margin-left: 0.5em;
}
dl > div:nth-child(1) {
  background-color: lightblue;
}
dl > div:nth-child(2) {
  background-color: lightgreen;
}
dl > div:nth-child(3) {
  background-color: pink;
}
<ul class="container">
  <li>
    <h2>Item 1</h2>
    <dl>
      <div><dt>attr1</dt>
        <dd>value a</dd>
      </div>
      <div><dt>attr2</dt>
        <dd>value b</dd>
      </div>
      <div><dt>attr3</dt>
        <dd>value c</dd>
      </div>
    </dl>
  </li>
  <li>
    <h2>Item 2 - Another One Here</h2>
    <dl>
      <div><dt>attr1</dt>
        <dd>value y -bla bla </dd>
      </div>
      <div><dt>attr2</dt>
        <dd>value some bit long</dd>
      </div>
      <div><dt>attr3</dt>
        <dd>value z</dd>
      </div>
    </dl>
  </li>
  <li>
    <h2>Item 3 - Another One Here</h2>
    <dl>
      <div><dt>attr1</dt>
        <dd>value x</dd>
      </div>
      <div><dt>attr2</dt>
        <dd>value some much longer</dd>
      </div>
      <div><dt>attr3</dt>
        <dd>value z - blabl bla</dd>
      </div>
    </dl>
  </li>
</ul>

(Codepen demo)

这里的困难在于 lidl 元素不是网格容器的直接子元素 - 您不能对其应用网格属性。

Grid Layout Module Level 2 - Subgrids(目前是一个草案规范)应该可以解决这个问题,但与此同时我们可以使用display:contents 来解决这个问题。

更多详情请见this post


如果你的标记一开始是平的,那么你就不需要display: contents,而 CSS 网格模块可以很好地做到这一点:

Cross-browser demo (With 'flat' markup')

.container {
  display: inline-grid;
  grid-column-gap: 1em;
  grid-template-columns: repeat(3,auto);
  padding: 0;
  background-color: white;
  padding-bottom: 0.5em;
  border-bottom: 2px dashed;
}

h2 {
  grid-column: 1 / -1;
  font-size: inherit;
  padding: 0.5em 0 0 0;
  border-top: 2px dashed;
}

dl, dt, dd {
  display: inline-block;
  padding: 0;
  margin: 0;
}
dt:after {
  content: ':'
}
dd {
 margin-left: 0.5em;
}
dl:nth-of-type(3n + 1) {
  background-color: lightblue;
}
dl:nth-of-type(3n + 2) {
  background-color: lightgreen;
}
dl:nth-of-type(3n) {
  background-color: pink;
}
<div class="container">
  <h2>Item 1</h2>
    <dl><dt>attr1</dt><dd>value a</dd></dl>
    <dl><dt>attr2</dt><dd>value b</dd></dl>
    <dl><dt>attr3</dt><dd>value c</dd></dl>
  <h2>Item 2 - Another One Here</h2>
    <dl><dt>attr1</dt><dd>value x</dd></dl>
    <dl><dt>attr2</dt><dd>value some bit long</dd></dl>
    <dl><dt>attr3</dt><dd>value z</dd></dl>
  <h2>Item 3 - Another One Here</h2>
    <dl><dt>attr1</dt><dd>value x</dd></dl>
    <dl><dt>attr2</dt><dd>value some much much much longer</dd></dl>
    <dl><dt>attr3</dt><dd>value z</dd></dl>
</div>

注意:

为了“收缩包装”网格,我将display: inline-grid 应用于网格容器。

【讨论】:

  • 也许我会使用&lt;dl&gt;&lt;dt&gt;Item 1&lt;/dt&gt;&lt;dd&gt;&lt;span&gt;attr&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;/dd&gt;&lt;dt&gt;Item 2&lt;/dt&gt;...&lt;/dl&gt; 来展平我的标记以避免display: content。无论如何,这似乎是个好主意。谢谢。
  • @tsh 我添加了一个带有平面标记的跨浏览器演示,还找到了一种更好的收缩包装方法:)
【解决方案2】:

只需将显示内联块添加到所有值...

dl *{
display:inline-block;
}
<ul>
<li>
  <h2>Item 1</h2>
  <dl>
    <div><dt>attr1</dt><dd>value a</dd></div>
    <div><dt>attr2</dt><dd>value b</dd></div>
    <div><dt>attr3</dt><dd>value c</dd></div>
  </dl>
</li>
<li>
  <h2>Item Another One Here</h2>
  <dl>
    <div><dt>attr1</dt><dd>value x</dd></div>
    <div><dt>attr2</dt><dd>value some bit long</dd></div>
    <div><dt>attr3</dt><dd>value z</dd></div>
  </dl>
</li>
</ul>

【讨论】:

    【解决方案3】:

    我使用浮动来对齐项目

    .f{
    	float:left;
    	margin:10px;
    }
    
    .c{
    	clear:both;
    }
    <ul>
    	<hr>
    <li>
    	
      <h2>Item 1</h2>
      <dl>
        <div class="f">attr1 value a</div>
    <!-- 		<div class="c"></div> -->
        <div class="f">attr2 value b</div>
        <div class="f">attr3 value c</div>
      </dl>
    	<div class="c"></div>
    </li>
    	<hr>
    <li>
      <h2>Item Another One Here</h2>
       <dl>
        <div class="f">attr1 value a</div>
    <!-- 		<div class="c"></div> -->
        <div class="f">attr2 value b</div>
        <div class="f">attr3 value c</div>
    		 	<div class="c"></div>
      </dl>
    </li>
    	<hr>
    </ul>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-03
      • 2017-08-02
      • 2019-07-06
      • 1970-01-01
      • 2014-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多