元素,可能会看到类似下图的说法,注意,这个说法是错误的,一本正经的胡说八道。\\n\\n也不知道从哪里爬过…","guid":"https://www.zhangxinxu.com/wordpress/?p=11729","author":"张 鑫旭","authorUrl":null,"authorAvatar":null,"publishedAt":"2025-07-10T10:11:02.731Z","media":[{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-10_180559.jpeg","type":"photo","width":394,"height":233},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-10_154019.png","type":"photo","width":642,"height":316},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-10_154257.png","type":"photo","width":726,"height":376},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-10_161658.png","type":"photo","width":166,"height":202},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-10_162309.png","type":"photo","width":153,"height":283},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-10_163718.png","type":"photo","width":641,"height":353},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-10_175946.jpeg","type":"photo","width":147,"height":97}],"categories":["HTML相关","html","Shadow DOM","语义化"],"attachments":null,"extra":null,"language":null},{"title":"好诶,select下拉框元素支持样式完全自定义啦!","url":"https://www.zhangxinxu.com/wordpress/2025/07/css-checkmark-select-customizable/","content":"by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11746 \\n本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
\\n
\\nTips:演示页面在本文最后。
\\n一、appearance:base-select \\n<select>
下拉框元素现在已经支持完全自定义了,太不容易了,太感动了。
\\nLuLu UI的Edge主题的Select组件现在已经接入了这个新特性。
\\n如果你的浏览器是Chrome 135+,可以访问这里 体验一下。
\\n
\\n如何实现? \\n为了不影响之前的Web效果,select下拉框的自定义需要设置新的属性值才可以。
\\n下拉框元素分为两部分,一个是按钮部分,一个是下拉部分。
\\n这两部分的自定义都需要额外的设置。
\\n其中按钮部分若想完全自定义,使用下面的CSS代码:
\\nselect {\\n appearance: base-select;\\n} \\n若想下拉部分的样式可以自定义,则需要使用::picker()
伪元素函数设置:
\\n::picker(select) {\\n appearance: base-select;\\n} \\n如果希望通过类名设置,例如:
\\n<select class=\\"ui-select\\"></select> \\n则:
\\n.ui-select,\\n.ui-select::picker(select) {\\n appearance: base-select;\\n} \\n\\n实时渲染效果如下所示:
\\n请选择:选项1选项2选项3选项4选项5选项6
\\n二、::picker-icon和::checkmark伪元素 \\n::picker-icon
伪元素是设置下拉按钮后面那个三角的,如下截图所示:
\\n
\\n::checkmark伪元素 \\n::checkmark
伪元素指向的是下拉列表选中选项前面的勾勾√,如下图所示:
\\n
\\n三、select列表的展开收起判断与动画 \\n列表展开的时候,会匹配伪类:open
,此时我们就可以对齐样式进行设置,例如,下拉列表显示的时候,边框高亮:
\\nselect:open {\\n border: 1px solid var(--ui-blue);\\n} \\n展开与收起动画 \\n下面是淡入淡出的展开与收起动画,大家可以参考下:
\\n::picker(select) {\\n opacity: 0;\\n transition: .2s allow-discrete;\\n}\\n::picker(select):popover-open {\\n opacity: 1;\\n}\\n@starting-style {\\n ::picker(select):popover-open {\\n opacity: 0;\\n }\\n} \\nallow-discrete
关键字还有@starting-style
规则我之前也介绍过,详见此文:“CSS transition-behavior让display none也有动画效果 ”
\\n四、option列表选中与禁用 \\n假设HTML元素如下:
\\n<select class=\\"ui-select\\">\\n <option value=\\"1\\" disabled>选项1</option>\\n <option value=\\"2\\">选项2</option>\\n <option value=\\"3\\">选项3</option>\\n <option value=\\"4\\" selected>选项4</option>\\n <option value=\\"5\\">选项5</option>\\n <option value=\\"6\\">选项6</option>\\n</select> \\n“选项1”是禁用的,“选项4”是选中的,都是有对应的伪类可以匹配的,分别是:disabled
或者:checked
。
\\noption:disabled {\\n color: gray;\\n}\\noption:checked {\\n color: green;\\n} \\n渲染效果如下图所示:
\\n
\\n五、optgroup与hr元素设置 \\n下拉列表支持两个元素,一个是<optgroup>
元素,这个支持已久,IE时代就支持。另外一个是 <hr>
元素,这个是最近这些年才支持的,好像就去年2024年吧。
\\n<optgroup>
元素如果设置label
属性,是会有分组标题的,效果示意:
\\n分组效果:\\n 选项 1.1\\n 选项 2.1选项 2.2\\n 选项 3.1选项 3.2选项 3.3\\n
\\n然而,经过我的测试,<optgroup>
生成的标题元素的样式设置是有限制的。
\\n也就是下图所示的::-internal-optgroup-label
伪元素在外部设置是无效的:
\\n
\\n更好的做法是使用<optgroup>
的::before
伪元素进行设置:
\\noptgroup::before {\\n content: attr(label);\\n /* 其他样式... */\\n} \\nhr元素 \\nhr元素可以用来实现分隔线效果。
\\n详见我全年写的这篇文章:“HTML select下拉框支持hr元素啦 ”
\\n六、base-select实现的原理 \\nbase-select
的下拉框的交互效果实际上借助了popover属性和CSS锚点定位元素实现的。
\\n1. popover属性 \\n下拉框进入自定义模式后,其定位和层级方式就不再是系统默认的交互方式,而是采用Web浏览器的popover
交互方式。
\\n具有顶层特性,显隐交互自动触发等特性。
\\n详见此文:“时代变了,该使用原生popover属性模拟下拉了 ”
\\n目前LuLu UI的Select组件就使用了此交互方式,针对Safari,Chrome等浏览器。
\\n2. CSS锚点定位 \\nCSS锚点定位可以实现跳出滚动限制的定位效果。
\\n详见此文:“全新的CSS Anchor Positioning锚点定位API ”
\\n目前LuLu UI的Select组件就使用了CSS锚点定位,采用渐进增强的方式。
\\n问题
\\nselect下拉框元素的CSS锚点定位采用的是自动定位方式,就是,如果下拉框页面偏下,或者列表很长,则列表在上面,默认则是列表朝下。
\\n根据我的实践,似乎没有办法判断下拉列表是朝上还是朝下。
\\n以及,列表会出现先朝上再朝下突然跳一下的不好的体验效果。
\\n因此,LuLu UI中的下拉框是默认朝下设置的,同时往上偏移1px:
\\n.ui-select::picker(select) {\\n appearance: base-select;\\n top: calc(anchor(bottom) - 1px);\\n} \\n如果想要朝上,手动添加类名进行更改。
\\n六、兼容性、演示页面、结语 \\n目前纯CSS自定义下拉框仅Chrome浏览器支持,如下截图所示:
\\n
\\n我估计Safari浏览器也会跟进的,按照以往的尿性,一年之后。
\\n演示页面 \\n还是放一个独立的演示页面吧,方便大家学习。
\\n您可以狠狠地点击这里:纯CSS自定义select下拉框的样式demo
\\n所有CSS代码都在页面上,是最复杂的下拉列表案例了,学会了这个,其他所有下拉都不在话下。
\\n
\\n感谢阅读,欢迎转发,银月(等周六现真容后补上)在这里谢谢你。
\\n😉😊😇 \\n🥰😍😘
\\n本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。 \\n本文地址:https://www.zhangxinxu.com/wordpress/?p=11746
\\n(本篇完)
","description":"by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11746 本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。\\n\\nTips:演示页面在本文最后。\\n\\n一、appearance:base-select\\n\\n下拉框元素现在已经支持完全自定义了,太不容易了,太感动了。\\n\\nLuLu UI的Edge主题的Select组件现在已经接入了这个新特性。\\n\\n如果你的浏览器是Chrome 135+,可以访问这里体验一下。\\n\\n如何实现?\\n\\n为了…","guid":"https://www.zhangxinxu.com/wordpress/?p=11746","author":"张 鑫旭","authorUrl":null,"authorAvatar":null,"publishedAt":"2025-07-04T03:03:45.045Z","media":[{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-4_110015.jpeg","type":"photo","width":393,"height":243},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-3_144632.png","type":"photo","width":468,"height":313},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-3_144825.png","type":"photo","width":335,"height":122},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-3_145803.png","type":"photo","width":319,"height":197},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-3_150729.png","type":"photo","width":242,"height":219},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-3_153216.png","type":"photo","width":428,"height":124},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-7-3_161638.png","type":"photo","width":642,"height":317},{"url":"https://image.zhangxinxu.com/image/blog/202507/2025-07-03_235445.png","type":"photo","width":378,"height":410}],"categories":["CSS相关","::checkmark","::picker-icon","@starting-style","allow-discrete","anchor-size()","appearance","base-select","hr","optgroup","option","popover","select","锚点定位"],"attachments":null,"extra":null,"language":null},{"title":"CSS小图标剪裁终极解决方案clip-path shape()函数","url":"https://www.zhangxinxu.com/wordpress/2025/06/css-clip-path-shape/","content":"by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11736 \\n本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
\\n
\\n一、告别path函数 \\nclip-path
的path()
函数可以传入SVG路径,从而实现元素的剪裁效果,比方说SVG小图标。
\\n例如:
\\nclip-path: path(\\"M 0 200 L 0,75 A 5,5 0,0,1 150,75 L 200 200 z\\"); \\n我多年前,我去,看了下,已经5年了,2020年的时候,有基于路径剪裁,研究了下“clipPath Sprites小图标技术 ”,还制作了配套的转换工具。
\\n但是最后实践下来,这个技术无人问津,包括我自己也不使用,原因就在于尺寸控制太麻烦。
\\n目前主流就是两种,一种是SVG图标元素直接内容,一种是CSS背景转移使用遮罩实现。
\\n这两种技术尺寸控制都非常方便,前者直接CSS尺寸设置,后者通过background-size等属性进行设置。
\\npath()函数的尺寸问题 \\n使用path()
函数,或使用url()
函数执行SVG元素的<path>
元素,都有尺寸无法自适应的问题。
\\n因为SVG路径里面的数值都是固定的像素px大小,在SVG元素中,这些大小与SVG外部尺寸关联,不会有问题,但是,放在CSS图像中,那就问题大了。
\\n例如,Font Awesome小图标SVG基本尺寸都是512*512,其path坐标值都是好几百的值。
\\n但是,CSS小图标的尺寸是20*20,如果应用几百数值的剪裁路径,小图标肯定就有问题,对不对?
\\n要么path坐标等比例缩小,要么CSS小图标尺寸也设成512像素,然后再zoom缩放,但这样实现就很麻烦。
\\n于是,在这个背景下,clip-path的shape()
函数应运而生。
\\n二、shape()函数的优势 \\n不妨对比下面两段剪裁应用代码,前者path()
函数,后者shape()
函数。
\\n.use-path {\\n clip-path: path(\'M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\');\\n} \\n.use-shape {\\n clip-path: shape(from 50% 0%,curve to 0% 50% with 22.38% 0%/0% 22.38%,smooth by 50% 50% with 22.38% 50%,smooth by 50% -50% with 50% -22.38%,smooth to 50% 0% with 77.62% 0%,close);\\n} \\n实现的都是圆形效果,如下图所示:
\\n
\\n区别在于,shape函数的指令不再是字符串,而是可自由调节的指令片段,就很自由。以及,shape函数的值是支持百分比值的,不再是固定的值,这个非常重要!
\\n因为这就意味着,当任意尺寸的元素应用shape()
函数的时候,剪裁的效果都是自动适应的,path()
函数的尺寸问题将不复存在。
\\n指令转换 \\n上面的shape()
函数中出现的单词from、curve、smooth等,其实与SVG的曲线绘制指令是一一对应的,这是我整理的对应关系表,极其含义,希望可以帮到大家的学习。
\\n\\n\\n\\n原始命令 \\n名称 \\nshape指令 \\n \\n \\n\\n\\nM/m \\n移动到/移动 \\nfrom to/from by \\n \\n\\nZ或z \\nclosepath 关闭路径 \\nclose \\n \\n\\nL/l \\n画线到/画线 \\nline to/line by \\n \\n\\nH/h \\n水平线到/水平线 \\nhline to/hline by \\n \\n\\nV/v \\n垂直线到/垂直线 \\nvline to/vline by \\n \\n\\nC/c、Q/q、T/t \\n三次贝塞尔曲线、二次贝塞尔曲线、光滑二次贝塞尔曲线 \\n均是curve to/curve by,具体参数不同 \\n \\n\\nS/s \\n光滑三次贝塞尔曲线 \\nsmooth to/smooth by \\n \\n\\nA/a \\n椭圆弧 \\narc to/arc by \\n \\n \\n
\\n还支持任意CSS数学函数 \\nshape()函数不仅支持百分比值,还支持calc计算、round 等数学函数,可以和CSS变量混合,示意:
\\n.flag {\\n --size: 40px;\\n clip-path: shape(\\n from 0px var(--size),\\n curve to 100% var(--size) \\n with 25% 0px / 75% calc(var(--size) * 2),\\n vline to calc(100% - var(--size)),\\n curve to 0 calc(100% - var(--size))\\n with 75% 100% / 25% calc(100% - var(--size) * 2),\\n close\\n )\\n} \\n因此,实现动画效果也非常方便,只需要使用@property规则,让CSS变量为数值类型就好了,详见此文:“Nice! Safari也支持CSS @property规则了 ”
\\n三、放心,有转换工具 \\n对于大多数前端开发人员而言,SVG的路径指令就是天书,看都看不到,还要转换成shape指令,岂不是要了他的狗命。
\\n不要担心,对此,我专门做了个在线的转换工具,当当当当。
\\n您可以狠狠地点击这里:CSS clip-path path() to shape()函数转换工具
\\n粘贴滤镜,点击转换按钮,然后点击复制就好了,右半区有演示页面,还支持直接上传SVG文件提取路径,如下截图所示:
\\n
\\n工具开发的匆忙,有什么使用问题,欢迎反馈,有什么建议和需求,也可以评论提出,我会抽空更新的哈。
\\n四、兼容性、点评与结语 \\nshape()
函数这个特性还比较新,我没有在caniuse上找到兼容性截图,不过支持数据还是有的,Chrome 135 和 Safari 18.4都有已经支持。
\\n只要这两个浏览器支持了,那就好说了,基本上,不出两年就可以再生产环境使用了。
\\n配合前端流工具,以后的小图标实现方案又多了一种选择。
\\n相比遮罩,clip-path的语义要更好,理解更方便,上手也更简单。
\\n我还是比较看好shape()
函数的应用前景的。
\\n好,就说这么多吧,本文还是值得转发转发的!
\\n妈呀,银月照片还没出来,先用这个代替吧。
\\n
\\n本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。 \\n本文地址:https://www.zhangxinxu.com/wordpress/?p=11736
\\n(本篇完)
","description":"by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11736 本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。\\n\\n一、告别path函数\\n\\nclip-path的path()函数可以传入SVG路径,从而实现元素的剪裁效果,比方说SVG小图标。\\n\\n例如:\\n\\nclip-path: path(\\"M 0 200 L 0,75 A 5,5 0,0,1 150,75 L 200 200 z\\");\\n\\n我多年前,我去,看了下,已经5年了…","guid":"https://www.zhangxinxu.com/wordpress/?p=11736","author":"张 鑫旭","authorUrl":null,"authorAvatar":null,"publishedAt":"2025-06-30T08:35:52.041Z","media":[{"url":"https://image.zhangxinxu.com/image/blog/202506/2025-6-30_163115.jpeg","type":"photo","width":371,"height":233},{"url":"https://image.zhangxinxu.com/image/blog/202506/2025-6-30_160715.png","type":"photo","width":744,"height":376},{"url":"https://image.zhangxinxu.com/image/blog/202506/2025-6-30_162850.jpeg","type":"photo","width":222,"height":145}],"categories":["CSS相关","clip-path","clipPath","CSS Shapes","path","shape()","贝塞尔曲线"],"attachments":null,"extra":null,"language":null}],"readCount":1099,"subscriptionCount":1514,"analytics":{"feedId":"41147805272531984","updatesPerWeek":1,"subscriptionCount":1514,"latestEntryPublishedAt":null,"view":0}}')