html - 如何在带有列表项的块子元素的html / css有序列表中使项目编号具有自适应性?
问题描述
目标
- 使有序列表自定义为
:before
允许的伪元素样式(AFAIK 任意形状是不可能的)。 - 容器内容边缘(即使左侧填充为 时也有边框
0
)和项目编号(指定为l
)之间的间距以及编号和项目(指定为m
)之间的间距必须是可调整的。 - 由于位数增加,项目编号必须是自适应的。
li
可以有子块元素,如div
,p
,figure
等。
问题
以下没有定位的解决方案满足前三个要求。
ol {
counter-reset: section;
}
ol li:before {
content: "";
display: inline-block;
counter-increment: section;
content: counters(section, ".") " ";
margin-left: 4px;
margin-right: 10px;
padding: 4px 6px;
background: lightblue;
border: 1px solid skyblue;
border-radius: 4px;
}
ol + li {
margin-top: 6px;
}
但是第四个要求呢?让我们尝试将子元素添加到li
:
<ol>
<li>Alpha</li>
<li>
<ol>
<li>
<p>Lorem ipsum</p>
<p>Duis aute</p>
</li>
</ol>
</li>
</ol>
从概念上讲,:before
伪元素必须占据一列(它下面的空间必须是空的,直到下一个li
)。目前,我只知道一种解决方案:定位。
ol {
counter-reset: section;
}
ol li {
position: relative;
}
ol li:before {
position: absolute;
left: 0;
counter-increment: section;
content: counters(section, ".") " ";
display: inline-block;
padding: 4px 6px;
background: lightblue;
border: 1px solid skyblue;
border-radius: 4px;
}
ol li + li {
margin-top: 12px;
}
ol li > li {
padding-left: 30px;
}
ol li > li > ol > li {
padding-left: 44px;
}
除了丑陋之外,这个解决方案只达到了第一个和第四个目标:
- 第二个目标我们不能再控制
l
了m
:我们只能控制总间距l + m + o
。 - 第三个目标没有适应性:这
l + m + o
仅适用于初始数字计数。
对于第四个目标,需要进行垂直间距调整,但并不难。
您能否提出一些替代解决方案?CSS 的灵活性到此结束了吗?
解决方案
这是一个使用 CSS 网格的想法,我将稍微调整您的初始代码:
ol {
counter-reset: section;
list-style:none;
margin:0;
padding:0;
}
ol li {
display:grid; /* added this */
grid-template-columns:auto 1fr; /* auto for the bullet and 1fr for the content*/
align-items:baseline; /* keep all the text aligned */
}
ol li:before {
content: "";
/* make sure the bullet span many rows os it's kept on the first column
and the content will placed on the second column
*/
grid-row:span 1000;
counter-increment: section;
content: counters(section, ".") " ";
margin-left: 4px;
margin-bottom:3px;
margin-right: 10px;
padding: 4px 6px;
background: lightblue;
border: 1px solid skyblue;
border-radius: 4px;
}
ol + li {
margin-top: 6px;
}
<ol>
<li>Alpha</li>
<li>
<ol>
<p>Something</p>
<li>
<p>Lorem ipsum</p>
<p>Duis aute</p>
</li>
</ol>
</li>
<li>Charlie</li>
<li>Delta</li>
<li>Echo</li>
<li>Foxtrotg</li>
<li>Golf</li>
<li>Hotel</li>
<li>India</li>
<li>Juliet</li>
</ol>
或者像下面这样:
ol {
counter-reset: section;
list-style:none;
margin:0;
padding:0;
}
ol li {
display:grid; /* added this */
grid-template-columns:auto 1fr; /* auto for the bullet and 1fr for the content*/
align-items:baseline; /* keep all the text aligned */
}
ol li > * {
grid-column:2; /* all the content in the second column and keep only the bullet in the first*/
}
ol li:before {
content: "";
counter-increment: section;
content: counters(section, ".") " ";
margin-left: 4px;
margin-bottom:3px;
margin-right: 10px;
padding: 4px 6px;
background: lightblue;
border: 1px solid skyblue;
border-radius: 4px;
}
ol + li {
margin-top: 6px;
}
<ol>
<li>Alpha</li>
<li>
<ol>
<p>Something</p>
<li>
<p>Lorem ipsum</p>
<p>Duis aute</p>
</li>
</ol>
</li>
<li>Charlie</li>
<li>Delta</li>
<li>Echo</li>
<li>Foxtrotg</li>
<li>Golf</li>
<li>Hotel</li>
<li>India</li>
<li>Juliet</li>
</ol>
推荐阅读
- google-apps-script - 如果在另一个脚本文件中,断点不起作用 - Google Script
- database - 如何在 sqlite 数据库中存储 CSV 格式的数据
- python - 在 kivy 退出时做点什么
- php - PHP 命名空间自动加载,需要作曲家吗?
- python - 烧瓶 API 格式
- android - Hilt 无法将 ContextImpl 转换为 Application
- python - 如何移动二次线?
- reactjs - 如何将 HOC 组件导航到 App 组件
- c# - 在 azure 上部署后 SignalR 无法正常工作。在 localhost 上工作
- reporting-services - SSAS/SSRS:没有百分比格式?