使用定义列表和网格布局创建 table

Create a table using definition list and grid layout

这是我尝试使用 <dl>display: grid 创建伪 table。

实际上,它有效。唯一的问题是,我被迫使用丑陋的方式来定义行。这是完全手动的方式。因此,如果我在 table 中有 30 行,那么为每一行重复 dt + dd + ... + dd 真的很愚蠢。

如何解决这个问题?

(我不想用真正的tables,因为它是为了Markdown)。

dl {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
}

dt {
    text-align: center;
}

dd {
    margin-left: 0;
}

dt, dd {
    border: 1px solid lightgray;
    padding: 0 1em;
}

/* Ugly part
 * (Red, yellow, and green colors are just for demo)
 */

dt {
    grid-row-start: 1;
}

dt + dd {
    grid-row-start: 2;
    color: rgb(244, 67, 54);
}

dt + dd + dd {
    grid-row-start: 3;
    color: rgb(255, 152, 0);
}

dt + dd + dd + dd {
    grid-row-start: 4;
    color: rgb(76, 175, 80);
}
<dl>
    <dt><p>Term 1</p></dt>
    <dd>
        <p>Definition of term 1 long long long long</p>
        <p>Lorem ipsum...</p>
        <p>Lorem ipsum...</p>
        <p>Lorem ipsum...</p>
    </dd>
    <dd><p>Definition of term 1</p></dd>
    <dd><p>Definition of term 1</p></dd>

    <dt><p>Term 2</p></dt>
    <dd><p>Definition of term 2</p></dd>
    <dd><p>Definition of term 2</p></dd>
    <dd><p>Definition of term 2</p></dd>

    <dt><p>Term 3</p></dt>
    <dd><p>Definition of term 3</p></dd>
    <dd><p>Definition of term 3</p></dd>
    <dd><p>Definition of term 3</p></dd>
</dl>

假设...您使用的是 Firefox 或 Chrome 但不是 IE/Edge :p,这是一个可行的解决方案,其中包含任意数量的术语以及每个术语的任意数量的定义:

➡️ Codepen

解释:

  1. 填充列后的网格列➡️grid-auto-flow: column;
  2. (grid items) 每个术语应该在第 1 行,所以它的定义在它下面 ➡️ dt { grid-row-start: 1 } 就像 "next column please"
  3. 创建足够多的显式行(比如 50),但只有在任何给定术语至少有 N 条定义(如果给定术语的最大定义为3. None 有4) ➡️ grid-template-rows: repeat(50, min-content);
  4. 然后尝试使用未定义数量的 columns/terms 但我无法通过显式列实现它(我想要类似 的东西“如果有内容则为 1fr,否则为 0” 与 minmax(),min|max-content 无济于事)。不过,使用隐式列就像一个魅力:➡️ grid-auto-columns: 1fr;

dl {
    display: grid;
    grid-auto-flow: column;
    /* doesn't assume 3 terms but N */
    grid-auto-columns: 1fr;
    grid-template-rows: repeat(50, min-content); /* doesn't assume 3 defs but M<50 */
}

dt {
    grid-row-start: 1; /* reset, next column */
}

另一种 (cross-browser) 方法是给父母定义列表相对定位:

dl {position: relative;}

然后给定义列表中的每个sub-element一个绝对位置。

dt, dd {display: block; position: absolute;}

(当然,因为我们现在使用的是绝对定位,所以只有当您清楚每个数据列的最大宽度和最大高度是多少时,这才是一个可行的替代方案每个数据行应该是)。

在这种情况下,您仍然需要为每个 dtdd 提供一个明确的 left 值,但是除了索引之外每次的声明都是相同的(引用三个次)像这样递增...

示例:

Index 2: dt:nth-of-type(2), dt:nth-of-type(2) ~ dd {left: calc((1px + 1em + 200px + 1em + 1px) * (2 - 1));}
Index 3: dt:nth-of-type(3), dt:nth-of-type(3) ~ dd {left: calc((1px + 1em + 200px + 1em + 1px) * (3 - 1));}
Index 4: dt:nth-of-type(4), dt:nth-of-type(4) ~ dd {left: calc((1px + 1em + 200px + 1em + 1px) * (4 - 1));}

等等

工作示例:

dl {
position: relative;
}

dt {
text-align: center;
font-weight: bold;
}

dt, dd {
display: block;
position: absolute;
width: 200px;
height: 50px;
min-height: 50px;
margin-left: 0;
border: 1px solid lightgray;
padding: 0 1em;
vertical-align: top;
}

dt {
top: 0;
}

dd:nth-of-type(3n - 2) {
top: 50px;
height: 200px;
color: rgb(244, 67, 54);
}

dd:nth-of-type(3n - 1){
top: 250px;
color: rgb(255, 152, 0);
}

dd:nth-of-type(3n) {
top: 300px;
color: rgb(76, 175, 80);
}

/* LEFT CO-ORDINATES */

dt:nth-of-type(2), dt:nth-of-type(2) ~ dd {
left: calc((1px + 1em + 200px + 1em + 1px) * (2 - 1));
}

dt:nth-of-type(3), dt:nth-of-type(3) ~ dd {
left: calc((1px + 1em + 200px + 1em + 1px) * (3 - 1));
}
<dl>
    <dt><p>Term 1</p></dt>
    <dd>
        <p>Definition of term 1 long long long long</p>
        <p>Lorem ipsum...</p>
        <p>Lorem ipsum...</p>
        <p>Lorem ipsum...</p>
    </dd>
    <dd><p>Definition of term 1</p></dd>
    <dd><p>Definition of term 1</p></dd>

    <dt><p>Term 2</p></dt>
    <dd><p>Definition of term 2</p></dd>
    <dd><p>Definition of term 2</p></dd>
    <dd><p>Definition of term 2</p></dd>

    <dt><p>Term 3</p></dt>
    <dd><p>Definition of term 3</p></dd>
    <dd><p>Definition of term 3</p></dd>
    <dd><p>Definition of term 3</p></dd>
</dl>

主要基于 FelipeAls 的回答,但更简单并且不需要人为的行数。

只需将 grid-auto-flow 改为 row,事情就变得简单了。

dl {
    display: grid;
    grid-auto-columns: 1fr;
    grid-auto-flow: row;
}

dt {
    grid-row: 1;
    background-color: lightgreen;
}

dt, dd {
    border: solid 1px silver;
    margin: 0;
}
    <dl>
        <dt><p>Term 1</p></dt>
        <dd>
            <p>A Definition of term 1 long long long long Lorem ipsum dolor sit amet, consectetur adipisicing elit. Non inventore impedit cum necessitatibus corporis, ratione culpa nesciunt corrupti recusandae voluptate, sint magni enim ullam quo, ipsum. Voluptatibus quos aliquid, optio!</p>
            <p>Lorem ipsum...</p>
            <p>Lorem ipsum...</p>
            <p>Lorem ipsum...</p>
        </dd>
        <dd><p>B Definition of term 1</p></dd>
        <dd><p>C Definition of term 1</p></dd>
        <dd>May the 4th</dd>

        <dt><p>Term 2</p></dt>
        <dd><p>A Definition of term 2</p></dd>
        <dd><p>B Definition of term 2</p></dd>
        <dd><p>C Definition of term 2</p></dd>

        <dt><p>Term 3</p></dt>
        <dd><p>A Definition of term 3</p></dd>
        <dd><p>B Definition of term 3</p></dd>
        <dd><p>C Definition of term 3</p></dd>
    </dl>