MoreRSS

site iconZhangXinXu | 张鑫旭修改

出版《CSS选择器世界》,喜欢钓鱼、写作。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

ZhangXinXu | 张鑫旭的 RSS 预览

全新的CSS border-shape属性简介

2026-06-10 11:00:06

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12232
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。

一句话,border-shape是用来实现不规则边框效果的。

一、这次不妨从案例入手

首先,我们使用AI生成一个五角星的勾勒路径。

帮我生成一个 五角星 SVG,使用 <path> 路径

使用模型Claude-Opus-4.6,总token 20,117,费用0.18元。

结果返回:

这是一个使用 <path> 绘制的五角星 SVG:

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
  <path d="M50 5 L61.8 38.2 L97.6 38.2 L68.9 59.5 L79.4 93.5 L50 73 L20.6 93.5 L31.1 59.5 L2.4 38.2 L38.2 38.2 Z" fill="#f5a623" stroke="#d4880f" stroke-width="1"/>
</svg>

或者使用更精确的数学计算版本(基于圆心 50,50,外径 45,内径 18):

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
  <path d="M50 5 L59.05 35.36 L91.27 35.36 L64.61 54.64 L73.66 84.99 L50 67.5 L26.34 84.99 L35.39 54.64 L8.73 35.36 L40.95 35.36 Z" fill="#f5a623" stroke="#d4880f" stroke-width="1"/>
</svg>

虽然border-shape属性支持path()函数,但是path()函数的绘制结果尺寸是固定的,适用场景受限,我们需要转换成更实用的shape()函数。

之前我在介绍“CSS小图标剪裁终极解决方案clip-path shape()函数”一文的时候,展示过一个工具,可以将path路径转为shape()函数语法。

您可以狠狠地点击这里: path() to shape()函数转换工具

这里我们只需要第一个简约版的路径就可以了,粘贴到第一个输入框,点击转换按钮,我们就可以得到shape()函数参数值了。

五角星转换示意

此时,我们就可以得到可以任意设置边框的五角星效果啦,HTML和CSS代码如下所示:

<style>
  .star {
    width: 150px;
    aspect-ratio: 1.076;
    border: dashed red;
    border-shape: shape(from 50% 0%,line to 62.39% 37.51%,line to 100% 37.51%,line to 69.85% 61.58%,line to 80.88% 100%,line to 50% 76.84%,line to 19.12% 100%,line to 30.15% 61.58%,line to 0% 37.51%,line to 37.61% 37.51%,close);
    box-shadow: 2px 2px 4px #0008;
    background: lightyellow;
  }
</style>
<canvas class="star"></canvas>

此时,便可以得到如下截图所示的渲染效果:

五角星绘制效果示意

通过上述效果我们可以得到以下结论:

  1. 设置了border-shape之后,border-style无效,边框类型永远是实线。
  2. 应用了边框形状之后,box-shadowoutlineborder-image等属性的轮廓计算区域也会跟着变化。

二、border-shape语法

border-shape的语法和clip-path是一样的,支持常规图像函数、shape()函数和path()函数。

例如:

border-shape: inset(22% 12% 15px 35px);
border-shape: circle(6rem at 12rem 8rem);
border-shape: ellipse(115px 55px at 50% 40%);
border-shape: polygon(
  50% 2.4%,
  34.5% 33.8%,
  0% 38.8%,
  25% 63.1%,
  19.1% 97.6%,
  50% 81.3%,
  80.9% 97.6%,
  75% 63.1%,
  100% 38.8%,
  65.5% 33.8%
);
border-shape: shape(...);
border-shape: path(...);

由于border-radius属性很好用,所以,border-shape属性的inset()circle()ellipse()基本上就没有出场的机会,大家可以把目光放在polygon()shape()这两个函数上。

例如:

<style>
  .star {
    width: 150px;
    aspect-ratio: 1;
    border: dotted red;
    border-shape: polygon(
      50% 2.4%,
      34.5% 33.8%,
      0% 38.8%,
      25% 63.1%,
      19.1% 97.6%,
      50% 81.3%,
      80.9% 97.6%,
      75% 63.1%,
      100% 38.8%,
      65.5% 33.8%
    );
    box-shadow: 2px 2px 4px #0008;
    background: lightyellow;
  }
</style>
<canvas class="star"></canvas>

也可以得到如下图所示的五角星效果。

polygon实现的五角星

三、兼容性以及其他说明

border-shape是一个相当新的CSS属性,目前只有Chrome 147+浏览器支持。

border-shape属性兼容性

对于不支持的浏览器,可以试试使用 clip-path + drop-shadow()滤镜近似模拟。

然后,这里有个codepen案例,演示了使用border-shape实现标签式导航条的效果,有兴趣的可以了解下。

标签式导航实现效果示意

碎碎念时间

对于复杂需求,超出自身能力边界的项目,还是不能全部交给AI。

这是最近团队出现的一个案例,极为复杂的需求,全AI生成,一周就用完所有预订token额度,功能也上线了,看起来还不错。

但随着后续需求增加,bug反馈也过来,其维护的成本惊人的增加。

由于代码都是AI生成的,开发者其实已经难以理解其中的实现细节,导致后续的token消耗相当惊人。

长远来看,是否提效了,是否节约成本了,还真难说。

我觉得,还是需要自己的思考的,平时对于技术还是要不断积累的,新的复杂需求上马,还是要技术预研的,整体的实现脉络还是要自己掌控的。

当然,如果是让AI实现自己根本实现不了的东西,那就另说,那就不是成本的问题,是有和无的区别了。

就是你

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12232

(本篇完)

CSS contrast-color()函数简介

2026-06-01 22:54:42

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12109
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。

一、无障碍访问专用颜色函数

CSS contrast-color()函数是专为无障碍访问设计的。

WCAG – Web Content Accessibility Guidelines(Web 内容无障碍指南)中有个概念叫做最小对比度(minimum contrast),意思是前景色和背景色的对比度一定不能小,否则色弱的用户会看不清楚文字,造成阅读障碍。

比方说很常见的,白底背景上千万不要是要颜色比较淡的灰色字。

实际上,由于淡灰色文字比较有设计感,广大的视觉设计师乐此不疲使用特别淡的灰色文字,实际上,这种设计是不友好的,我就遇到过公司老板级别的人反馈怎么文字都不见了,实际上是由于对比度太低,显示器没能很好渲染出来。

contrast-color()颜色函数可以根据提供的颜色,自动返回对比度最友好的颜色。

注意,说的是对比度最友好的颜色,而不是反相,这是有根本区别的。

contrast-color()返回的色值只能是白色white或者黑色black。

语法使用示意:

contrast-color(red)
contrast-color(var(--backgroundColor))

二、效果示意

眼见为实,下面的demo是实时渲染的,RSS订阅的文章应该是看不到效果的,可以访问原文体验:

请改变背景色:

其中,按钮背景色和文字颜色代码如下:

button {
  background-color: var(--button-color, black);
  color: contrast-color(var(--button-color, black));
}

可以看到,随着颜色的选择,文字颜色会自动匹配白色或者黑色,保证对比度都在一个合适的范围内。

而在之前,相关的实现需要大量的代码,已经巧妙使用颜色的边界特性才能实现。

详见此文:CSS文字和背景color自动配色技术简介

看了下日期,啧啧,已经是8年前的文章了。

自动配色按钮示意

兼容性

目前所有主流浏览器都已经支持了这个函数,如下截图所示:

contrast-color兼容性

可以麻溜的用起来啦,点个赞!

三、小兔子结语哗啦啦

在中国,只要是与无障碍访问相关的前端特性,一定是无人问津的,contrast-color()也不例外,因为缺少强制的法律约束,全靠自觉,也就是所谓的工程师的追求。

追求?这东西早些年还很看重,如今已经很少听到这个词了。

就比方说抖音Web端的视频上传页面,里面的问题多如牛毛,改动是很勤快,没几个星期就能看到一些变化,结果呢,越改越差,无力吐槽,有时候真想自己上去帮忙搞定。

那个封面制作,一开始套用模板,文字可以自定义,现在完全不行,文字内容数量一旦不一致,丑死了;那渲染,还有AI书封生成,从来没成功过,一直在loading,然后下面的缩略图也无法拖动,生成速度也一言难尽。

这种水平,莫不是代码都是AI生成的?看不到一点追求!

扯远了,回到这里。

contrast-color()还是需要传递色值才能返回黑白,还是弱了点,如果就这种程度,我觉得以后很少会有前端人员使用它。

要是它可以自动识别背景,不仅是颜色,也可以是图片这些,然后自动配色,那倒是值得称赞一番。

比方说字幕颜色使用白色还是黑色,对吧,要是可以自动识别,这个函数就实用了。

眼下么,我觉得只能当做玩具使用了。

好了,懒得多扯淡了,感谢阅读,欢迎分享,么么哒。

😉😊😇
🥰😍😘

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12109

(本篇完)

新特性速递:focus()行为新增focusVisible控制

2026-05-29 16:23:06

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12203
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。

一、focus()的两种控制

平时让一个输入框聚焦,我们可以这么设置:

input.focus();

默认情况下,控件元素通过focus()方法获取焦点,浏览器会通过滚动的方式让元素重定位到页面可视区域内。

但有时候,这种行为会影响体验,毕竟页面会突然跳一下。

如果不希望这种滚动行为触发,可以这么设置。

input.focus({
  preventScroll: true
})

此特性已支持多年,我也多次在生产环境使用。

preventScroll兼容性

那么本文要介绍的focusVisible又是什么呢?

二、focusVisible参数的作用

focusVisible可以控制元素获得焦点的时候,是否显示浏览器内置的outline轮廓效果。

先看一个案例,如下HTML代码:

<a href id="link">链接</a>
<button onclick="link.focus()">点击我</button>

此时,点击按钮,链接是没有焦点效果的。

这在开发中其实是有用户体验的问题的,用户并不知道这个链接是否真的被聚焦了,除非有专门的CSS定义,例如:

:any-link:focus {
  color: red;
}

效果示意:

链接文字颜色变红

不过针对每一个控件元素设置focus效果是啰嗦的,在一些对视觉要求不那么高的场合,通过focusVisible参数进行控制是最快捷的方法,例如:

<a href id="link">链接</a>
<button onclick="link.focus({focusVisible: true})">点击我</button>

点击按钮后的效果示意:

焦点效果示意

如果大家对自己手头的浏览器足够自信,也可以点击下面的按钮,亲自感受下聚焦后的轮廓效果。

链接

当然,focusVisible也能用来关闭浏览器默认的轮廓效果。

例如下面的输入框获得焦点后,浏览器的发光轮廓是不会显示的。

<input id="input" type="text">
<button onclick="input.focus({focusVisible: false})">点击我</button>

一般与无障碍访问与用户体验相关的特性,在国内总是无人问津,因为缺少对应的法律法规约束。

所以focusVisible这个特性注定知者寥寥,加上其兼容性,我对其未来的应用程度表示并不乐观。

fousVisible兼容性

三、难得碎碎念

说实话,在AI时代,对AI模型的关注和研究,我已经落后于现在的年轻人了。

我不是做管理的,如果我带着一个团队,我会花很多时间思考这些模型和工具对团队生产力的赋能,因为那可以体现我的价值,或者说为数不多可以体验价值,或者至少让上级看到价值的地方。

虽说单纯的专业技术人员也能做这样的事情,但是,考虑到“上下左右”的现实障碍(这里写了不少,都删掉了,怕厂子的公关过来提醒),是很难推动的,所以很难让我投入大量的精力在这个上面。

作为一个纯专业立足的前端开发,究竟什么才是自己的核心竞争力,这个问题我其实一直在思考。

为什么会一直思考呢?

因为每次分享那些实用或不实用的前端技术,都会有人评论,现在都AI了,学这个还有什么用。

我的回答是:

如果我的水平比AI还要强,我实现的东西比AI实现的还要好,那我是不是不要担心被AI替代,这是不是我的核心竞争力!

人的精力是有限的,尤其到了我现在这个年纪,再像10年前那样,每天研究前端到凌晨1~2点,是不可能了,只能舍弃工具层面的关注与研究,继续把精力放在语言本身上。

那些好的,可能不稳定的特性,那些特别新的但是很高效的实现上。

比方说最近的项目使用scroll-state滚动容器查询:

@container excel-scroller scroll-state(scrolled: right) {
  /* 第一列粘性定位启用的时候,出现右边框 */
  :where(td, th):first-child {
    border-right: 1px solid var(--ui-border);
  }
}

AI绝对不会想到这么实现,为何?

一是训练的代码库还没有这样的的代码;二是AI为了项目稳定,一定会使用更加稳健的传统实现,虽然说最终也都能实现最终的效果,但是代码质量天差地别。

作为一个对兼容性要求不那么高的项目,AI生产的稳健代码并非是最好的实现,如果只是单纯使用AI生成一个能跑的东西,为何需要用你呢?换个更便宜的年轻人岂不更好。

不过,想要变得专业层面,至少某一个领域比AI强,还是很难的,而且越往后越难,这个之后的文章再碎碎念吧。

OK,就这样吧,感谢阅读,欢迎分享。

😉😊😇
🥰😍😘

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12203

(本篇完)

1分钟速度了解text-align match-parent声明

2026-05-25 16:41:37

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12196
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。

一、直接进入正题

text-align:match-parent声明的作用就是使用和父元素一样的对齐方式。

可仔细一想,这个属性值就很奇怪,text-align本身就具有继承特性,为何还要多此一举设计一个match-parent呢?

因为现实开发中存在一个极为罕见的使用场景。

且看案例:

<div class="box">
  <p id="p">我的对齐是?</p>
</div>
.box {
  text-align: end;
}

此时,如果我们想要得知<p>元素的textAlign计算值,得到的结果会是 end

console.log(getComputedStyle(p).textAlign);
// 结果是 'end'

end? any problem?

这不很正常吗,不是理所当然的吗?

非也非也!

比方说下图所示的对称布局:

对称布局示意

最简单高效的实现就是使用CSS逻辑属性,外加direction属性控制方向。

text-align:end就是逻辑属性。

下面问题来了,我们我希望知道布局列表中的元素是左对齐还是右对齐,会发现运行getComputedStyle(p).textAlign这行代码是无效的。

因为无论哪个方位,返回的都是end,而不是left或者right

正是由于这样的场景存在,于是设计了match-parent

比方说,我们把上面的CSS代码换成:

.box {
  text-align: end;
  p {
    text-align: -webkit-match-parent;
    text-align: match-parent;
  }
}

此时,默认情况下,<p>元素的textAlign计算值就是right.

console.log(getComputedStyle(p).textAlign);
// 结果是 'right'

如果此时<p>元素的上下文处于 direction: rtl 环境中,那么返回的textAlign计算值则回是 left

这就是text-align:match-parent声明的唯一作用,可以返回当前元素精确对齐方向left/right,而不是含糊其辞的start/end。


二、注定很少使用的特性

direction属性本身就很少使用,毕竟属于CSS布局高级技巧。

加上需要获取textAlign计算值的场景本身就很小众。

所以,在实际生产环境需要用到match-parent的概率近乎是0.

可以说就是一个玩具特性,大家了解下有这么个东西就好了。

最后看下其兼容性,出乎意料,虽然作用鸡肋,但是兼容性却出奇的好,全都支持,就是Chrome浏览器还需要加-webkit-私有前缀。

text-align: match-parent兼容性

装逼作用

如果抛开match-parent原本的作用,我们不是不可以在生产环境使用,不如这样,所有需要使用 text-align:inherit 代码的地方,全部替换成 text-align:match-parent,虽然渲染效果是一样的,但是装逼效果天差地别,同事一看你写的代码,顿时高山仰止,“望其项背”,爽!

爽表情包

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12196

(本篇完)

光标的形状也能设置了,就是CSS caret-shape属性

2026-05-18 15:50:42

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12180
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。

一、温故知新:光标颜色

2018年的时候,分享过CSS改变光标颜色的caret-color属性,详见“CSS改变光标颜色caret-color简介及其它变色方法”一文。

现在,除了光标的颜色,光标的形状也能改变了,这个CSS属性就是caret-shape属性。

caret-shape: auto;
caret-shape: bar;
caret-shape: block;
caret-shape: underscore;

二、caret-shape效果一览

属性值bar的效果就是目前我们常见的效果,一根1像素的竖条条像小星星一样闪啊闪的。

这个不不放图。

block的光标效果是一个方块闪啊闪的,效果如下GIF动图:

block光标效果示意

当我们输入的字符会覆盖下一个字符的时候,就适合使用caret-shape:block块状光标。

underscore是下划线光标效果。GIF录屏效果参见:

下划线光标

当我们需要模仿打字机或下划线文本输入样式效果的时候,那就可以使用caret-shape:underscore下划线插入符号光标。

三、caret-animation属性是?

caret-shape属性同时出现的还有个CSS属性,名为caret-animation,用来控制光标闪烁与否的。

语法如下:

/* 动感光波,闪闪闪 */
caret-animation: auto;
/* 糟了,中了定身咒 */
caret-animation: manual;

当我们希望自定义光标闪烁效果的时候,就可以用到caret-animation:manual,例如下面这个案例,七色光标变色闪烁效果。

<input placeholder="focus me" class="custom-caret" />

CSS代码如下:

@keyframes custom-blink {
  0%, 50% { caret-color: transparent; }
  50%, 100% { caret-color: hsl(calc(3.6 * var(--seed)), 100%, 50%); }
}

@property --seed {
  syntax: "<integer>";
  inherits: true;
  initial-value: 0;
}

@keyframes seed {
  from { --seed: 0; }
  to { --seed: 100; }
}

.custom-caret {
  caret-animation: manual; /* 关闭默认的光标闪烁 */
  caret-color: blue;
  animation: custom-blink 1.5s infinite step-end, seed calc(1.5s * 7) both infinite linear;
}

眼见为实,您可以狠狠地点击这里:CSS自定义caret光标七色动画demo

由于光标比较细,其实效果没那么明显,如下GIF动图。

光标变色动画效果

四、caret缩写属性

caret-colorcaret-animationcaret-shape可以缩写为caret属性。

caret: red;
caret: block;
caret: manual;

/* 两个值 */
caret: red manual;
caret: block auto;
caret: underscore orange;

/* 三个值 */
caret: bar manual red; 
caret: block auto #00ff00;

由于三个属性的值类型都不一样,所以缩写属性数量任意,顺序也没有什么要求,一眼就看出什么意思。

不过日常开发不建议缩写,因为兼容性不一致。

caret-color很早就支持,但是你如果使用caret缩写属性设置光标颜色,本来支持的浏览器反而不支持。

所以,caret属性大家暂时先了解了解就可以了。

五、兼容性and结语么么😘

兼容性么,咳咳,暂时仅Chrome浏览器支持,还在这是个渐进增强特性,浏览器不支持,也就是默认效果,不影响在实际开发中的使用。

caret-shape兼容性

结语了,该说些什么呢。

现在年纪上去了,没有多少分享欲了。

算了,不扯淡了,就这样吧。

动感光波

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12180

(本篇完)