这篇文章发布于 2025年07月4日,星期五,11:03,归类于 CSS相关。 阅读 731 次, 今日 724 次 没有评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11746
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
Tips:演示页面在本文最后。
一、appearance:base-select
<select>
下拉框元素现在已经支持完全自定义了,太不容易了,太感动了。
LuLu UI的Edge主题的Select组件现在已经接入了这个新特性。
如果你的浏览器是Chrome 135+,可以访问这里体验一下。
如何实现?
为了不影响之前的Web效果,select下拉框的自定义需要设置新的属性值才可以。
下拉框元素分为两部分,一个是按钮部分,一个是下拉部分。
这两部分的自定义都需要额外的设置。
其中按钮部分若想完全自定义,使用下面的CSS代码:
select { appearance: base-select; }
若想下拉部分的样式可以自定义,则需要使用::picker()
伪元素函数设置:
::picker(select) { appearance: base-select; }
如果希望通过类名设置,例如:
<select class="ui-select"></select>
则:
.ui-select, .ui-select::picker(select) { appearance: base-select; }
实时渲染效果如下所示:
请选择:
二、::picker-icon和::checkmark伪元素
::picker-icon
伪元素是设置下拉按钮后面那个三角的,如下截图所示:
::checkmark伪元素
::checkmark
伪元素指向的是下拉列表选中选项前面的勾勾√,如下图所示:
三、select列表的展开收起判断与动画
列表展开的时候,会匹配伪类:open
,此时我们就可以对齐样式进行设置,例如,下拉列表显示的时候,边框高亮:
select:open { border: 1px solid var(--ui-blue); }
展开与收起动画
下面是淡入淡出的展开与收起动画,大家可以参考下:
::picker(select) { opacity: 0; transition: .2s allow-discrete; } ::picker(select):popover-open { opacity: 1; } @starting-style { ::picker(select):popover-open { opacity: 0; } }
allow-discrete
关键字还有@starting-style
规则我之前也介绍过,详见此文:“CSS transition-behavior让display none也有动画效果”
四、option列表选中与禁用
假设HTML元素如下:
<select class="ui-select"> <option value="1" disabled>选项1</option> <option value="2">选项2</option> <option value="3">选项3</option> <option value="4" selected>选项4</option> <option value="5">选项5</option> <option value="6">选项6</option> </select>
“选项1”是禁用的,“选项4”是选中的,都是有对应的伪类可以匹配的,分别是:disabled
或者:checked
。
option:disabled { color: gray; } option:checked { color: green; }
渲染效果如下图所示:
五、optgroup与hr元素设置
下拉列表支持两个元素,一个是<optgroup>
元素,这个支持已久,IE时代就支持。另外一个是 <hr>
元素,这个是最近这些年才支持的,好像就去年2024年吧。
<optgroup>
元素如果设置label
属性,是会有分组标题的,效果示意:
分组效果:
然而,经过我的测试,<optgroup>
生成的标题元素的样式设置是有限制的。
也就是下图所示的::-internal-optgroup-label
伪元素在外部设置是无效的:
更好的做法是使用<optgroup>
的::before
伪元素进行设置:
optgroup::before { content: attr(label); /* 其他样式... */ }
hr元素
hr元素可以用来实现分隔线效果。
详见我全年写的这篇文章:“HTML select下拉框支持hr元素啦”
六、base-select实现的原理
base-select
的下拉框的交互效果实际上借助了popover属性和CSS锚点定位元素实现的。
1. popover属性
下拉框进入自定义模式后,其定位和层级方式就不再是系统默认的交互方式,而是采用Web浏览器的popover
交互方式。
具有顶层特性,显隐交互自动触发等特性。
详见此文:“时代变了,该使用原生popover属性模拟下拉了”
目前LuLu UI的Select组件就使用了此交互方式,针对Safari,Chrome等浏览器。
2. CSS锚点定位
CSS锚点定位可以实现跳出滚动限制的定位效果。
详见此文:“全新的CSS Anchor Positioning锚点定位API”
目前LuLu UI的Select组件就使用了CSS锚点定位,采用渐进增强的方式。
问题
select下拉框元素的CSS锚点定位采用的是自动定位方式,就是,如果下拉框页面偏下,或者列表很长,则列表在上面,默认则是列表朝下。
根据我的实践,似乎没有办法判断下拉列表是朝上还是朝下。
以及,列表会出现先朝上再朝下突然跳一下的不好的体验效果。
因此,LuLu UI中的下拉框是默认朝下设置的,同时往上偏移1px:
.ui-select::picker(select) { appearance: base-select; top: calc(anchor(bottom) - 1px); }
如果想要朝上,手动添加类名进行更改。
六、兼容性、演示页面、结语
目前纯CSS自定义下拉框仅Chrome浏览器支持,如下截图所示:
我估计Safari浏览器也会跟进的,按照以往的尿性,一年之后。
演示页面
还是放一个独立的演示页面吧,方便大家学习。
您可以狠狠地点击这里:纯CSS自定义select下拉框的样式demo
所有CSS代码都在页面上,是最复杂的下拉列表案例了,学会了这个,其他所有下拉都不在话下。
感谢阅读,欢迎转发,银月(等周六现真容后补上)在这里谢谢你。
😉😊😇
🥰😍😘
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=11746
(本篇完)
- HTML select下拉框支持hr元素啦 (0.468)
- 告别JS浮层,全新的CSS Anchor Positioning锚点定位API (0.277)
- CSS3 appearance大全鉴赏以及是否影响box-sizing (0.128)
- CSS transition-behavior让display none也有动画效果 (0.128)
- 666,看hr标签实现分隔线如何玩出花 (0.085)
- 聊聊Top Layer顶层特性的隐患与实践 (0.085)
- 查漏补缺,我仍未知道的HTML nonce和popover属性 (0.064)
- 时代变了,该使用原生popover属性模拟下拉了 (0.064)