WebGL Tutorial
and more

Styling CSS List

撰写时间:2025-04-07

修订时间:2025-04-10

默认效果

  • Item1
  • Item2
    • AAA
    • BBB
    • CCC
  • Item3

默认缩进

ul { border: .1px solid #FFF9; & li { border: .1px solid #FFF5; } }
  • Item1
  • Item2
    • AAA
    • BBB
    • CCC
  • Item3

li标签有缩进,且li的子元素ul也有缩进。

各浏览器对ul的默认CSS设置如下:

ul { display: block; list-style-type: disc; margin-block-start: 1em; margin-block-end: 1em; padding-inline-start: 40px; }

padding-inline-start设置了一个从哪开始计算行内padding的偏移值,最终的padding值为:

value = padding-inline-start + padding-left;

上面代码,padding-inline-start的值被设置为40px,该属性值将被各个子标签继承,导致了其每一级子标签,包括liul,均从父标签的当前位置先向右缩进40px后再开始计算padding,从而形成了分级缩进的效果。

Marker

list-style-position

list-style-position指定列表项目的图标位置。

ul { border: .1px solid #FFF9; margin: 1em; & li { border: .1px solid #FFF5; list-style-position: outside; /* default setting */ } } ul.inside li { list-style-position: inside; }
  • Item1
  • Item2
  • Item3
  • Item1
  • Item2
  • Item3

list-style-position的默认值为outside,则图标位于列表项目的盒子外部的左边。当其值为inside时,图标位于列表项目的盒子内部的左边。

ul { border: .1px solid #FFF9; margin: 1em; & li { border: .1px solid #FFF5; list-style-position: outside; /* default setting */ padding-left: 2em; } } ul.inside li { list-style-position: inside; }
  • Item1
  • Item2
  • Item3
  • Item1
  • Item2
  • Item3

当给li设置padding-left值时,outside类型的图标不会动,而inside类型的图标则紧随其文本内容向右移动。

但两种类型的图标位置均受padding-inline-start的值的影响。

ul { border: .1px solid #FFF9; margin: 1em; padding-inline-start: 0px; & li { border: .1px solid #FFF5; list-style-position: outside; /* default setting */ padding-left: 0em; } } ul.inside li { list-style-position: inside; }
  • Item1
  • Item2
  • Item3
  • Item1
  • Item2
  • Item3

如果li::before的设置,则图标位于::before内容的左边。

ul { border: .1px solid #FFF9; margin: 1em; & li { border: .1px solid #FFF5; list-style-position: outside; /* default setting */ padding-left: 2em; &::before { content: '\272A'; display: inline-block; width: 3em; margin: 0 1em; text-align: center; border: .1px solid gray; } } } ul.inside li { list-style-position: inside; }
  • Item1
  • Item2
  • Item3
  • Item1
  • Item2
  • Item3

list-style-type

div#container { margin: 0.2em; display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1em; & div { border: .1px solid gray; border-radius: 0.5em; & ul { margin: 0.2em auto; } & p { color: limegreen; text-align: center; margin: 0.2em auto; } } }
let listStyleTypes = ['disc', 'circle', 'square', 'decimal', 'decimal-leading-zero', 'lower-roman', 'upper-roman', 'lower-greek', 'lower-latin', 'upper-latin', 'armenian', 'georgian', 'lower-alpha', 'upper-alpha', 'lower-greek']; function createULs() { let target = document.querySelector('#container'); target.innerHTML = ''; for (let style of listStyleTypes) { let ul = document.createElement('ul'); ul.style.listStyleType = style; for (let i = 0; i < 5; i++) { let li = document.createElement('li'); li.textContent = `Item${i}`; ul.appendChild(li); } let p = document.createElement('p'); p.textContent = style; let div = document.createElement('div'); div.appendChild(ul); div.appendChild(p); target.appendChild(div); } } createULs();

list-style-image

ul { list-style-image: url(/imgs/info-dark.png); }
  • Item1
  • Item2
  • Item3

list-style

如果图标文件不存在,可使用第2个参数额外指定默认的图标类型。

ul { list-style: url(/imgs/unexisted.png) disc; }
  • Item1
  • Item2
  • Item3

可使用一或多个Unicode字符作为图标。可使用Unicode编码值为\20的空格来添加间距。

ul { list-style: "\23F5 \20 \2606 \20"; }
  • Item1
  • Item2
  • Item3

下面形成多级缩进的多图标效果。

ul { list-style: "\23F5 \20 \2606 \20" inside; padding-inline-start: 2em; & li { border: .1px solid #FFF5; &::before { content: "\25CE \20"; } } }
  • Item1
  • Item2
    • A
    • B
    • C
  • Item3

设置content内容

我们不能直接设置content的尺寸大小,但可通过背景图像,精细改变其大小及位置。

li { border: .1px solid gray; display: flex; padding: 10px; justify-content: left; align-items: center; } li::before { content: ''; width: 32px; height: 32px; padding-right: 3em; margin-right: 2em; background-image: url(/js/esm/three/manual/examples/resources/images/happyface.png); background-size: contain; /*background-repeat: no-repeat;*/ filter: brightness(80%); }
  • Item1
  • Item2
  • Item3

lidisplay设置为flex,可以很方便地分别调节图标及文本。

首先,设置为flex后,其效果先将list-style-type设置为none

其次,在li上设置padding,将同时影响图标及文本。

再次,在::before中设置padding-leftpadding-right,如果背景图像允许重复,则上面所设置的空间用于重复平铺背景图像。在::before中设置margin-left,同时影响图标及文本的左边距;设置margin-right,只影响文本的左边距;设置margin-topmargin-bottom,只影响图标的上下边距。

树形控件

实现最基本的设置

ul.treeview, ul.treeview ul { margin: 0; padding: 0 0 0 2em; } ul.treeview li { list-style: none; position: relative; } ul.treeview li::before { position: absolute; content: ''; top: -0.1em; left: -0.5em; width: 0.4em; height: 0.615em; border-style: none none solid solid; border-width: 0.1px; border-color: gray; } ul.treeview li:not(:last-child)::after { position: absolute; content: ''; top: 0; left: -0.5em; bottom: 0; border-style: none none none solid; border-width: 0.1px; border-color: gray; }
  • 中国
    • 北京
    • 广东省
      • 广州市
      • 韶关市
    • 海南省
      • 海口市
        • 美兰区
        • 龙华区
        • 秀英区
        • 琼山区
      • 三亚市
    • 安徽省
      • 合肥市
      • 安庆市
  • United States of America
    • Washington
    • Florida

锦上添花

第一步:敲定基本版面

ul.treeview { margin: 1em; /*padding: 1em;*/ padding-inline-start: 2.4em; background-color: var(--blue-02); & ul, li { color: white; background-color: var(--dark-body-bg-color); filter: brightness(95%); } & li { border: .1px solid #FFF1; line-height: 1.5em; &:has(> ul) { list-style: "\23F7 \20 \2606 \20"; } &:not(:has(> ul)) { list-style: circle; } } }
  • 中国
    • 北京
    • 广东省
      • 广州市
      • 韶关市
    • 海南省
      • 海口市
        • 美兰区
        • 龙华区
        • 秀英区
        • 琼山区
      • 三亚市
    • 安徽省
      • 合肥市
      • 安庆市

第二步:图标与连线

/* basic layout */ ul.treeview { margin: 1em; padding-inline-start: 2.4em; & ul, li { color: white; filter: brightness(95%); } & li { line-height: 2em; &:has(> ul) { list-style: "\23F7 \20 \1F4C2 \20"; } &:not(:has(> ul)) { list-style: "\2606 \20"; } } } /* linking nodes */ ul.treeview { --line-left-offset: -4.6em; & li { position: relative; } & li::before { position: absolute; content: ''; top: -1em; left: var(--line-left-offset); width: 2.2em; height: 2em; border-style: none none solid solid; border-width: 0.1px; border-color: gray; } & li:not(:last-child)::after { position: absolute; content: ''; top: 0em; left: var(--line-left-offset); bottom: 0em; border-style: none none none solid; border-width: 0.1px; border-color: gray; } }
  • 中国
    • 北京
    • 广东省
      • 广州市
      • 韶关市
    • 海南省
      • 海口市
        • 美兰区
        • 龙华区
        • 秀英区
        • 琼山区
      • 三亚市
    • 安徽省
      • 合肥市
      • 安庆市

第三步:用户交互

/* basic layout */ ul.treeview { margin: 1em; padding-inline-start: 0em; & li { color: var(--dark-body-color); } & li { line-height: 2em; &:has(> ul) { list-style: "\23F7 \20 \1F4C2 \20"; } &:not(:has(> ul)) { list-style: "\2606 \20"; } } } /* linking nodes */ ul.treeview { --line-left-offset: -4.6em; & li { position: relative; } & li::before { position: absolute; content: ''; top: -1em; left: var(--line-left-offset); width: 2.2em; height: 2em; border-style: none none solid solid; border-width: 0.1px; border-color: gray; } & li:not(:last-child)::after { position: absolute; content: ''; top: 0em; left: var(--line-left-offset); bottom: 0em; border-style: none none none solid; border-width: 0.1px; border-color: gray; } } /* setting states */ ul.treeview { box-sizing: border-box; border: .1px solid deepskyblue; border-radius: 0.3em; padding-left: 3em; overflow: auto; width: 250px; height: 600px; white-space: nowrap; background-color: var(--dark-body-bg-color); & li { cursor: default; -webkit-user-select: none; user-select: none; &.selected { color: white; background-color: hsl(from #306791 h 30% l / 0.7); border-radius: 0.1em; > ul { background-color: var(--dark-body-bg-color); } } :has(> ul.collapsed) { list-style: "\23F5 \20 \1F4C1 \20"; } > ul.collapsed { display: none; } } }
let selectedItem = null; let treeview = document.querySelector('ul.treeview'); let lis = treeview.querySelectorAll('li'); lis.forEach(li => { li.addEventListener('click', (evt) => { if (selectedItem) { selectedItem.classList.remove('selected'); } li.classList.toggle('selected'); selectedItem = li; let childUL = li.querySelector('ul'); if (childUL) { childUL.classList.toggle('collapsed'); } evt.stopPropagation(); }); });
  • 中国
    • 北京
    • 广东省
      • 广州市
      • 韶关市
    • 海南省
      • 海口市
        • 美兰区
        • 龙华区
        • 秀英区
        • 琼山区
      • 三亚市
    • 安徽省
      • 合肥市
      • 安庆市

参考资源

  1. CSS2.2 Lists