CSS 具有 2 个列标题的网格 4 列布局 <dl>
CSS Grid 4 column layout with 2 column titles for <dl>
给定一个标记:
dl
dt
dd
dd
..
dt
dd
dd
...
我正在尝试使用 CSS 网格实现以下布局:
dt dt
dd dd dd dd
dd dd dd dd
dd dd dd dd
dd dd dd dd
我目前的做法是:
.time-table {
display: grid;
grid-gap: 1em;
grid-template-columns: repeat(4, 1fr);
grid-template-areas:
"destination1 destination1 destination2 destination2"
"time time time time";
list-style: none;
padding: 0;
}
.time-table__time {
background-color: #34ace0;
display: block;
color: #fff;
margin: 0;
grid-area: time;
}
.time-table__destination::before {
content: '1D2';
display: inline-block;
transform: translateX(-5px);
}
.time-table__destination1 {
grid-area: destination1;
}
.time-table__destination2 {
grid-area: destination2;
}
@media (max-width: 35em) {
.time-table {
grid-template-columns: repeat(2, 1fr);
grid-template-areas:
"destination1 destination2"
"time time";
}
.time-table__destination::before {
transform: translateX(-5px);
}
}
<dl class="time-table">
<dt class="time-table__destination time-table__destination1">Metsakooli</dt>
<dd class="time-table__time">23:22</dd>
<dd class="time-table__time">23:32</dd>
<dd class="time-table__time">23:42</dd>
<dd class="time-table__time">23:52</dd>
<dd class="time-table__time">00:02</dd>
<dt class="time-table__destination time-table__destination2">Männiku</dt>
<dd class="time-table__time">23:27</dd>
<dd class="time-table__time">23:37</dd>
<dd class="time-table__time">23:47</dd>
<dd class="time-table__time">23:57</dd>
<dd class="time-table__time">00:07</dd>
</dl>
或者不使用网格的模板区域:
.time-table {
display: grid;
grid-gap: 1em;
grid-template-columns: repeat(4, 1fr);
list-style: none;
padding: 0;
}
.time-table__time {
background-color: #34ace0;
display: block;
color: #fff;
margin: 0;
}
.time-table__destination::before {
content: '1D2';
display: inline-block;
transform: translateX(-5px);
}
@media (max-width: 35em) {
.time-table {
grid-template-columns: repeat(2, 1fr);
grid-template-areas:
"destination1 destination2"
"time time";
}
.time-table__destination::before {
transform: translateX(-5px);
}
}
<dl class="time-table">
<dt class="time-table__destination time-table__destination1">Metsakooli</dt>
<dd class="time-table__time">23:22</dd>
<dd class="time-table__time">23:32</dd>
<dd class="time-table__time">23:42</dd>
<dd class="time-table__time">23:52</dd>
<dd class="time-table__time">00:02</dd>
<dt class="time-table__destination time-table__destination2">Männiku</dt>
<dd class="time-table__time">23:27</dd>
<dd class="time-table__time">23:37</dd>
<dd class="time-table__time">23:47</dd>
<dd class="time-table__time">23:57</dd>
<dd class="time-table__time">00:07</dd>
</dl>
但是如您所见,第一种方法无法在适当的路线标题下呈现不同的时间。第二种方法创建了行,但没有以正确的顺序列出它们并且无法提升第二个标题 ()。我的问题是:
- 如何让时间 (<dd>
) 出现在它们各自的 destination/route 下?
- 是否有更优雅的方法让第一行的单元格跨越 2 列,并让其余元素代替网格区域 time
,例如使用 grid-auto-rows
? (我打赌有...)
您提供的 HTML 的问题是无法将 <dd>
元素与唯一的 <dt>
元素相关联,.time-table__time
元素应该对齐。
使用 JavaScript 可以利用 order
属性 来提供视觉标识,但这是对可以更好地解决的问题的过度解决方案通过更改 HTML.
正如您所发现的,使用 grid-template-areas
的问题在于您创建了一个跨越四列的命名区域;并且所有 <dd>
元素都放在那个命名区域中。
修改后的 HTML 下面使用两个 <dl>
元素,每个元素都有自己的 <dt>
和 <dd>
后代,以将两者唯一地关联在一起;那些 <dl>
元素本身包裹在 <li>
元素中,它们本身是 <ol>
元素的 children。这是因为您显示的 HTML – 没有上下文 – 似乎 是一个有序的目的地列表。
我很想将 <dl>
元素本身更改为 <ol>
元素,因为它们似乎是有序的时间列表,尽管有标题。然而,撇开语义不谈,以下是我对如何产生明显需求的建议:
/* Setting the margin and padding of all
elements to zero: */
*,
::before,
::after {
margin: 0;
padding: 0;
}
/* Adjust to taste: */
html,
body {
background-color: #fff;
}
/* Defining a custom CSS Property for
later use: */
:root {
--numParentColumns: 2;
}
/* Removing default list-styling: */
ol,
li,
dl,
dt,
dd {
list-style-type: none;
}
ol {
/* Setting the display type of the <ol> element
to that of 'grid': */
display: grid;
/* Defining the grid columns, using the previously-
defined --numParentColumns variable to supply the
integer to the repeat() function, and setting each
column to the width of 1fr: */
grid-template-columns: repeat(var(--numParentColumns), 1fr);
/* Adjust to taste: */
width: 90vw;
grid-column-gap: 0.5em;
margin: 0 auto;
}
ol>li dl {
/* Setting the <dl> elements' display to 'grid': */
display: grid;
/* Defining the number of grid columns to that value
held in the --numParentColumns variable, retaining
the 1fr width: */
grid-template-columns: repeat(var(--numParentColumns), 1fr);
grid-column-gap: 0.25em;
}
dt.time-table__destination {
/* Rather than using specific named grid-areas
here we place the <dt> elements in column 1
and span 2 columns: */
grid-column: 1 / span 2;
background-color: limegreen;
}
dt.time-table__destination::before {
content: '1D2';
margin: 0 1em 0 0;
}
dd.time-table__time {
background-color: #34ace0;
}
/* in displays where the width is at, or below,
35em we update some properties: */
@media (max-width: 35em) {
dd.time-table__time {
/* Here we place the <dd> elements in the
first column and have them span 2
columns: */
grid-column: 1 / span 2;
}
}
/* At page-widths less than 15em (not mentioned in
the question): */
@media (max-width: 15em) {
/* We update the --numParentColumns variable to
1, as a tangential demonstration of how useful
CSS custom properties can be: */
:root {
--numParentColumns: 1;
}
}
<ol>
<li>
<dl>
<dt class="time-table__destination time-table__destination1">Metsakooli</dt>
<dd class="time-table__time">23:22</dd>
<dd class="time-table__time">23:32</dd>
<dd class="time-table__time">23:42</dd>
<dd class="time-table__time">23:52</dd>
<dd class="time-table__time">00:02</dd>
</dl>
</li>
<li>
<dl class="time-table">
<dt class="time-table__destination time-table__destination2">Männiku</dt>
<dd class="time-table__time">23:27</dd>
<dd class="time-table__time">23:37</dd>
<dd class="time-table__time">23:47</dd>
<dd class="time-table__time">23:57</dd>
<dd class="time-table__time">00:07</dd>
</dl>
</li>
</ol>
参考文献:
@DavidThomas 的 answer 帮了我很多,但我最终走向了一个不同的方向。我发现伪元素被认为是网格单元!这为使用 aria 标签作为 <ol>
标题提供了一个很好的机会,我想要的结果如下所示:
.time-table {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 3em;
text-align: center;
color: #fff;
}
.time-table__listing {
display: grid;
grid-gap: 1em;
grid-template-columns: repeat(2, 1fr);
list-style: none;
--listing-background: #34ace0;
}
.time-table__listing:last-child {
--listing-background: #B33771;
}
.time-table__listing::before {
content: '1D2 ' attr(aria-label);
font-size: 1.2em;
grid-column: 1 / span 2;
}
.time-table__listing:first-child::before {
background-color: #34ace0;
}
.time-table__listing:last-child::before {
background-color: #B33771;
}
.time-table__time {
background-color: var(--listing-background);
}
<div class="time-table">
<ol aria-label="Metsakooli" class="time-table__listing">
<li class="time-table__time bg-bright-three">23:22</li>
<li class="time-table__time bg-bright-three">23:32</li>
<li class="time-table__time bg-bright-three">23:42</li>
<li class="time-table__time bg-bright-three">23:52</li>
<li class="time-table__time bg-bright-three">00:02</li>
</ol>
<ol aria-label="Männiku" class="time-table__listing">
<li class="time-table__time bg-bright-three">23:27</li>
<li class="time-table__time bg-bright-three">23:37</li>
<li class="time-table__time bg-bright-three">23:47</li>
<li class="time-table__time bg-bright-three">23:57</li>
<li class="time-table__time bg-bright-three">00:07</li>
</ol>
</div>
给定一个标记:
dl
dt
dd
dd
..
dt
dd
dd
...
我正在尝试使用 CSS 网格实现以下布局:
dt dt
dd dd dd dd
dd dd dd dd
dd dd dd dd
dd dd dd dd
我目前的做法是:
.time-table {
display: grid;
grid-gap: 1em;
grid-template-columns: repeat(4, 1fr);
grid-template-areas:
"destination1 destination1 destination2 destination2"
"time time time time";
list-style: none;
padding: 0;
}
.time-table__time {
background-color: #34ace0;
display: block;
color: #fff;
margin: 0;
grid-area: time;
}
.time-table__destination::before {
content: '1D2';
display: inline-block;
transform: translateX(-5px);
}
.time-table__destination1 {
grid-area: destination1;
}
.time-table__destination2 {
grid-area: destination2;
}
@media (max-width: 35em) {
.time-table {
grid-template-columns: repeat(2, 1fr);
grid-template-areas:
"destination1 destination2"
"time time";
}
.time-table__destination::before {
transform: translateX(-5px);
}
}
<dl class="time-table">
<dt class="time-table__destination time-table__destination1">Metsakooli</dt>
<dd class="time-table__time">23:22</dd>
<dd class="time-table__time">23:32</dd>
<dd class="time-table__time">23:42</dd>
<dd class="time-table__time">23:52</dd>
<dd class="time-table__time">00:02</dd>
<dt class="time-table__destination time-table__destination2">Männiku</dt>
<dd class="time-table__time">23:27</dd>
<dd class="time-table__time">23:37</dd>
<dd class="time-table__time">23:47</dd>
<dd class="time-table__time">23:57</dd>
<dd class="time-table__time">00:07</dd>
</dl>
或者不使用网格的模板区域:
.time-table {
display: grid;
grid-gap: 1em;
grid-template-columns: repeat(4, 1fr);
list-style: none;
padding: 0;
}
.time-table__time {
background-color: #34ace0;
display: block;
color: #fff;
margin: 0;
}
.time-table__destination::before {
content: '1D2';
display: inline-block;
transform: translateX(-5px);
}
@media (max-width: 35em) {
.time-table {
grid-template-columns: repeat(2, 1fr);
grid-template-areas:
"destination1 destination2"
"time time";
}
.time-table__destination::before {
transform: translateX(-5px);
}
}
<dl class="time-table">
<dt class="time-table__destination time-table__destination1">Metsakooli</dt>
<dd class="time-table__time">23:22</dd>
<dd class="time-table__time">23:32</dd>
<dd class="time-table__time">23:42</dd>
<dd class="time-table__time">23:52</dd>
<dd class="time-table__time">00:02</dd>
<dt class="time-table__destination time-table__destination2">Männiku</dt>
<dd class="time-table__time">23:27</dd>
<dd class="time-table__time">23:37</dd>
<dd class="time-table__time">23:47</dd>
<dd class="time-table__time">23:57</dd>
<dd class="time-table__time">00:07</dd>
</dl>
但是如您所见,第一种方法无法在适当的路线标题下呈现不同的时间。第二种方法创建了行,但没有以正确的顺序列出它们并且无法提升第二个标题 ()。我的问题是:
- 如何让时间 (<dd>
) 出现在它们各自的 destination/route 下?
- 是否有更优雅的方法让第一行的单元格跨越 2 列,并让其余元素代替网格区域 time
,例如使用 grid-auto-rows
? (我打赌有...)
您提供的 HTML 的问题是无法将 <dd>
元素与唯一的 <dt>
元素相关联,.time-table__time
元素应该对齐。
使用 JavaScript 可以利用 order
属性 来提供视觉标识,但这是对可以更好地解决的问题的过度解决方案通过更改 HTML.
正如您所发现的,使用 grid-template-areas
的问题在于您创建了一个跨越四列的命名区域;并且所有 <dd>
元素都放在那个命名区域中。
修改后的 HTML 下面使用两个 <dl>
元素,每个元素都有自己的 <dt>
和 <dd>
后代,以将两者唯一地关联在一起;那些 <dl>
元素本身包裹在 <li>
元素中,它们本身是 <ol>
元素的 children。这是因为您显示的 HTML – 没有上下文 – 似乎 是一个有序的目的地列表。
我很想将 <dl>
元素本身更改为 <ol>
元素,因为它们似乎是有序的时间列表,尽管有标题。然而,撇开语义不谈,以下是我对如何产生明显需求的建议:
/* Setting the margin and padding of all
elements to zero: */
*,
::before,
::after {
margin: 0;
padding: 0;
}
/* Adjust to taste: */
html,
body {
background-color: #fff;
}
/* Defining a custom CSS Property for
later use: */
:root {
--numParentColumns: 2;
}
/* Removing default list-styling: */
ol,
li,
dl,
dt,
dd {
list-style-type: none;
}
ol {
/* Setting the display type of the <ol> element
to that of 'grid': */
display: grid;
/* Defining the grid columns, using the previously-
defined --numParentColumns variable to supply the
integer to the repeat() function, and setting each
column to the width of 1fr: */
grid-template-columns: repeat(var(--numParentColumns), 1fr);
/* Adjust to taste: */
width: 90vw;
grid-column-gap: 0.5em;
margin: 0 auto;
}
ol>li dl {
/* Setting the <dl> elements' display to 'grid': */
display: grid;
/* Defining the number of grid columns to that value
held in the --numParentColumns variable, retaining
the 1fr width: */
grid-template-columns: repeat(var(--numParentColumns), 1fr);
grid-column-gap: 0.25em;
}
dt.time-table__destination {
/* Rather than using specific named grid-areas
here we place the <dt> elements in column 1
and span 2 columns: */
grid-column: 1 / span 2;
background-color: limegreen;
}
dt.time-table__destination::before {
content: '1D2';
margin: 0 1em 0 0;
}
dd.time-table__time {
background-color: #34ace0;
}
/* in displays where the width is at, or below,
35em we update some properties: */
@media (max-width: 35em) {
dd.time-table__time {
/* Here we place the <dd> elements in the
first column and have them span 2
columns: */
grid-column: 1 / span 2;
}
}
/* At page-widths less than 15em (not mentioned in
the question): */
@media (max-width: 15em) {
/* We update the --numParentColumns variable to
1, as a tangential demonstration of how useful
CSS custom properties can be: */
:root {
--numParentColumns: 1;
}
}
<ol>
<li>
<dl>
<dt class="time-table__destination time-table__destination1">Metsakooli</dt>
<dd class="time-table__time">23:22</dd>
<dd class="time-table__time">23:32</dd>
<dd class="time-table__time">23:42</dd>
<dd class="time-table__time">23:52</dd>
<dd class="time-table__time">00:02</dd>
</dl>
</li>
<li>
<dl class="time-table">
<dt class="time-table__destination time-table__destination2">Männiku</dt>
<dd class="time-table__time">23:27</dd>
<dd class="time-table__time">23:37</dd>
<dd class="time-table__time">23:47</dd>
<dd class="time-table__time">23:57</dd>
<dd class="time-table__time">00:07</dd>
</dl>
</li>
</ol>
参考文献:
@DavidThomas 的 answer 帮了我很多,但我最终走向了一个不同的方向。我发现伪元素被认为是网格单元!这为使用 aria 标签作为 <ol>
标题提供了一个很好的机会,我想要的结果如下所示:
.time-table {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 3em;
text-align: center;
color: #fff;
}
.time-table__listing {
display: grid;
grid-gap: 1em;
grid-template-columns: repeat(2, 1fr);
list-style: none;
--listing-background: #34ace0;
}
.time-table__listing:last-child {
--listing-background: #B33771;
}
.time-table__listing::before {
content: '1D2 ' attr(aria-label);
font-size: 1.2em;
grid-column: 1 / span 2;
}
.time-table__listing:first-child::before {
background-color: #34ace0;
}
.time-table__listing:last-child::before {
background-color: #B33771;
}
.time-table__time {
background-color: var(--listing-background);
}
<div class="time-table">
<ol aria-label="Metsakooli" class="time-table__listing">
<li class="time-table__time bg-bright-three">23:22</li>
<li class="time-table__time bg-bright-three">23:32</li>
<li class="time-table__time bg-bright-three">23:42</li>
<li class="time-table__time bg-bright-three">23:52</li>
<li class="time-table__time bg-bright-three">00:02</li>
</ol>
<ol aria-label="Männiku" class="time-table__listing">
<li class="time-table__time bg-bright-three">23:27</li>
<li class="time-table__time bg-bright-three">23:37</li>
<li class="time-table__time bg-bright-three">23:47</li>
<li class="time-table__time bg-bright-three">23:57</li>
<li class="time-table__time bg-bright-three">00:07</li>
</ol>
</div>