好诶,select下拉框元素支持样式完全自定义啦!

这篇文章发布于 2025年07月4日,星期五,11:03,归类于 CSS相关。 阅读 731 次, 今日 724 次 没有评论

 

下拉框样式完全自定义封面图,头图

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;
}

渲染效果如下图所示:

option元素状态匹配

五、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浏览器支持,如下截图所示:

base-select的兼容性

我估计Safari浏览器也会跟进的,按照以往的尿性,一年之后。

演示页面

还是放一个独立的演示页面吧,方便大家学习。

您可以狠狠地点击这里:纯CSS自定义select下拉框的样式demo

所有CSS代码都在页面上,是最复杂的下拉列表案例了,学会了这个,其他所有下拉都不在话下。

下拉框完全自定义模拟

感谢阅读,欢迎转发,银月(等周六现真容后补上)在这里谢谢你。

😉😊😇
🥰😍😘

(本篇完)

分享到:


发表评论(目前没有评论)