MoreRSS

site iconZhangXinXu | 张鑫旭修改

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

Inoreader Feedly Follow Feedbin Local Reader

ZhangXinXu | 张鑫旭的 RSS 预览

text-wrap进化:支持两子属性和pretty stable新值

2025-06-18 16:37:08

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

text-wrap封面图

一、前文回顾,balance属性值

两年前有介绍过text-wrap:balance的作用,详见“5分钟快速了解text-wrap:balance的作用”此文。

这个声明还是挺好用的,特别适合用在可换行的水平列表排列上。

比方说过去,点赞头像这种布局,就可能第一行很多,第二行很少:

点赞传统实现排版

使用text-wrap:balance之后,可以让两行的数量接近,布局效果很好很多。

点赞新的排版实现

现在text-wrap又支持了两个新的属性值,pretty和stable。

二、值pretty和stable的作用

1. text-wrap:pretty

按照MDN上的说法,text-wrap:pretty声明和text-wrap:wrap是一样的,区别在于text-wrap:pretty更注重排版,而非性能,也就是wrap的算法速度更快。

所以我就很好奇,既然prettywrap效果一样,性能还更差,那为何还要设计出来呢?

后来查了个资料,终于明白prettywrap的差异了,text-wrap:pretty可以避免最后一行过短。

MDN页面的demo我通过添加文字,让最后一行只露出一个单词,终于看到了两者的区别,如下GIF所示:

排版区别GIF

按照规范上的说法,不同浏览器对pretty的理解是可以不一样的,可就是Firefox,Safari之类可能是另外的排版美化效果,上图展示的事Chrome下的表现。

目前,Chrome117+版本支持该值,Safari即将支持,Firefox还未支持。

text-wrap pretty兼容性

2. text-wrap:stable

stable的作用,按照文档的说法,也是和wrap没有什么区别。只有当文本内容处于标记状态的时候,text-wrap:stable可以让编辑内容前面的行内容保持稳定,而不会整个文本内容发生排版变化。

嗯……我反复尝试了下,未能复现。反正意思就是,如果元素是contenteditable可编辑的,那么建议设置text-wrap:stable,只有好处,没有坏处。

目前Chrome 130+版本支持属性值stable,奇怪的是,此属性值Safari和Firefox也都已经支持了,这个现象倒是有趣。

stable的兼容性

三、子属性text-wrap-mode

由于text-wrap属性的值愈发复杂,因此,开始有了子属性,text-wrap就变成了合并属性,类似于text-decorationborder-image这类CSS属性。

两个子属性,一个是text-wrap-mode,还有一个是text-wrap-style

text-wrap-mode这个属性超级简单,单看语法就知道怎么使用的了:

/* 换行显示 */
text-wrap-mode: wrap;
/* 不自动换行显示 */
text-wrap-mode: nowrap;

不过考虑到兼容性,我们目前还是使用white-space属性比较合适:

/* 换行显示 */
white-space: wrap;
/* 不自动换行显示 */
white-space: nowrap;

四、子属性text-wrap-style

直接看text-wrap-style属性的语法:

/* 正常换行显示 */
text-wrap-style: auto;
/* 每行内容尽可能相等 */
text-wrap-style: balance;
/* 最后一行不要太短 */
text-wrap-style: pretty;
/* 保持前面行数排版稳定 */
text-wrap-style: stable;

text-wrap-modetext-wrap-style这两个属性的兼容性是一样的,都是今年刚支持的新特性。

text-wrap子属性兼容性

五、结语

还是balance属性值实用,最近新支持的几个CSS属性和方法,你不能说他毫无用处,只能说只有一丢丢用处,给我感觉,就是规范制定那群人,不整点新东西,就好像工作不饱和,自己失去了存在价值一般。

有点类似于公司里面想一些无效的需求,来解决那么多人的就业问题一样。

注定扫入历史垃圾箱的几个新特性。

好吧,就说这么多,感谢阅读,我的侍妾慕沛灵希望大家多多转发。

慕沛灵

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

(本篇完)

CSS ::scroll-button ::scroll-marker伪元素又是干嘛用的?

2025-06-13 16:24:36

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

scroll snap 按钮自定义封面图

先回答题目抛出的问题,一句话:

::scroll-button可以自定义上下或左右滚动按钮,::scroll-marker可以自定义切换按钮,用在CSS Scroll Snap交互场景下,以便实现完整的Carousel,Slider等交互效果。

一、一反常态,先上案例

先看::scroll-button()伪元素使用场景,可以模拟Scroll Snap上一项和下一项切换展示效果。

您可以狠狠地点击这里:CSS ::scroll-button实现slide左右切换demo

可以看到图片slider左右有切换按钮,点击的时候,图片就会左右滑动,非常的流畅,整个交互过程没有任何JS的参与。

如下MP4录屏所示(不动点击播放):

其中还使用了锚点定位技术,有兴趣的可以参见“全新的CSS Anchor Positioning锚点定位API”这篇文章。

核心代码

其中,HTML结构比较简单:

<zxx-slide>
  <a href="###"><img src="ps1.jpg"></a>
  <a href="###"><img src="ps2.jpg"></a>
  <a href="###"><img src="ps3.jpg"></a>
  <a href="###"><img src="ps4.jpg"></a>
</zxx-slide>

CSS核心代码如下所示(完整代码访问demo获取):

zxx-slide {
  overflow: auto;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;

  a {
    scroll-snap-align: start;
  }
}

zxx-slide::scroll-button(left) {
  content: "◄";
}

zxx-slide::scroll-button(right) {
  content: "►";
}
zxx-slide {
  anchor-name: --myCarousel;
}

zxx-slide::scroll-button(*) {
  position: absolute;
  position-anchor: --myCarousel;
}
zxx-slide::scroll-button(*) {
  align-self: anchor-center;
}
zxx-slide::scroll-button(left) {
  right: calc(anchor(left) - 45px);
}

zxx-slide::scroll-button(right) {
  left: calc(anchor(right) - 45px);
}

使用了很多CSS新特性,如果不是持续关注CSS的前端开发,上面的代码多半都已经不认识了。

::scroll-button()伪元素函数语法

支持的参数包括下面这些:

::scroll-button(*) {}
::scroll-button(left) {}
::scroll-button(up) {}
::scroll-button(right) {}
::scroll-button(down) {}
::scroll-button(block-end) {}
::scroll-button(block-start) {}
::scroll-button(inline-end) {}
::scroll-button(inline-start) {}

注意,垂直访问是up/down,而不是top/bottom。

常规的CSS属性都支持,因此,我们可以自如地对切换按钮进行样式自定义。

二、::scroll-marker使用案例

::scroll-marker的是要要更复杂些,需要和scroll-marker-group属性以及::scroll-marker-group伪元素配合使用。

还是通过案例快速上手吧。

您可以狠狠地点击这里:CSS ::scroll-marker实现slide序号切换demo

页面效果如下,点击下面的序号按钮,图片就会平滑滚动到对应的位置,如下截屏动画所示(不播放就“戳”一下):

很赞,对不对?

核心代码

HTML和上面demo一样,主要看下CSS部分:

zxx-slide {
  display: flex;
  overflow: auto;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scroll-marker-group: after;

  a {
    scroll-snap-align: start;
    counter-increment: markers;

    &::scroll-marker {
      content: counter(markers);
      /*... */
    }
  }

  ::scroll-marker:target-current {
    background-color: #cd0000;
    color: white;
  }
}

::scroll-marker-group {
  display: flex;
  place-content: center;
}

这里出现了一个新的伪类:target-current,表示当选匹配的marker选项。

scroll-marker-group属性

scroll-marker-group属性的作用:控制包含::scroll-marker-group伪元素的滚动容器是否生成,如果生成,位置是前还是后。

使用示意:

/* 索引序号组在滚动容器前面 */
scroll-marker-group: before;
/* 索引序号组在滚动容器后面 */
scroll-marker-group: after;
/* 默认值,不显示索引序号组 */
scroll-marker-group: none;

::scroll-marker-group伪元素

::scroll-marker伪元素的父级容器元素,控制索引序号整体位置、样式用的。

具体使用参见上面的样式页面。

三、兼容性以及结语若干

本文介绍的这几个伪元素和CSS属性都需要Chrome 135+支持,是比较新的一个特性。

scroll-marker scroll-button兼容性

::column伪元素

::column伪元素也是同一时间支持的伪元素,也是用在CSS carousel 效果中的,和上面的区别在于,水平布局是使用columns布局实现。

此时,若还是按照本文的案例使用,则需要这么使用:

zxx-slide::column {
  scroll-snap-align: center;
}
zxx-slide::column::scroll-marker {
  content: "";
  /* 按钮样式... */
}
zxx-slide::column::scroll-marker:target-current {
  background-color: #cd0000;
}

具体不展开,因为columns布局用的人本就少,别说这个伪元素的。

使用::column的目的是不影响原本的columns布局。

最后,本文::scroll-button::scroll-marker伪元素生成的交互按钮,天然支持无障碍访问,很棒!

好吧,就说这么多,又是学习的一天!

😉😊😇
🥰😍😘

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

(本篇完)

JS PageSwap PageReveal事件干嘛用的?

2025-06-04 17:51:19

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

JS PageSwap PageReveal事件封面图

一、总算有点眉目了

PageSwapEvent事件是一个新支持的全局事件,其兼容性如下:

PageSwapEvent事件

目前Safari和Chrome均支持此事件类型。

乍一看,这个事件与页面选项卡切换相关,对吧,Swap就是交换的意思,但是,如果你在页面中写下类似这样的测试代码,是看不到任何效果的。

window.addEventListener("pageswap", (event) => {
  console.log(event);
});

怎么回事,难道这个事件不是这样执行的?对,没错,不是这样执行的。

这个事件必须与页面级可视动画View Transitions API一同使用才有效果。

不知大家阅读过之前这篇热文没有:“页面级可视动画View Transitions API初体验

其中展示了一个案例,就是页面A调整到页面B(直接刷新的那种跳转),也是可以有transition过渡效果的。

这里有演示页面,您可以狠狠地点击这里:传统跳转页面变得单页一样滑来滑去demo

页面滑来滑去示意

而JS PageSwapEvent事件就是为了这个交互场景而设计的。

二、PageSwap事件语法与作用

如果我们的Web页面设置了页面级别的view-transition,包含下面这段CSS代码:

@view-transition {
  navigation: auto;
}

那么当页面准备卸载(unload)的时候,pageswap实践就会触发。

如果仅仅是普通的页面跳转,是不会有事件触发的。

我们可以对比下效果,比方说这个测试页面:纯粹的页面刷新跳转demo

页面中设置了pageswap事件代码:

window.addEventListener("pageswap", (event) => {
  console.log(event);
});

但是,我们点击链接跳转的时候,只有导航提示,并没有任何console输出,如下截图所示:

普通跳转控制台提示

但是,如果是上面的滑来滑去demo,我们可以在控制台看到PageSwapEvent对象的输出(需要开启Preserve log选项),如下图所示:

pageSwap对象输出截图示意

所以,PageSwapEvent事件是伴随View Transitions API一同出现的事物。

语法

PageSwapEvent对象支持两个只读属性,分别是:

activation
包含一个NavigationActivation对象,该对象包含同一源导航的导航类型以及当前和目标文档历史条目。如果导航在重定向链中的任何位置都有跨源URL,则返回null
viewTransition
返回表示入站跨文档视图转换的ViewTransition对象(如果事件触发时有一个处于活动状态)。若非如此,则返回null。

至于返回对象的细节,这里不深入。

三、PageReveal事件表示进入

pageswap表示当前页面离开,那么进入则是PageReveal事件。

window.addEventListener("pagereveal", (event) => {
  console.log(event);
});

pagereveal对象展示

不过语法上有所区别,仅支持viewTransition这个只读属性:

viewTransition
包含一个ViewTransition对象,表示跨文档导航的活动视图转换。

其他就没什么好讲的了。

三、好了,了解这么多足够了

一方面受制于兼容性,另一方面受制于PageSwapEvent事件的小众应用场景,再一方面受制于前端行业进入稳定期,再再一方面由于AI的出现,注定PageSwap事件是个很少有人会真正在生产环境使用的特性。

冷门知识,小众特性,虽然有设计价值,但注定无人问津。

大家了解下有这么个东西就好了。

其他就没什么好说的了,感谢大家的阅读,我们下一篇文章再见。

😉😊😇
🥰😍😘

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

(本篇完)

震惊,有生之年居然看到CSS attr()全属性支持

2025-05-28 14:19:08

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

css attr全属性支持

一、真的是有生之年系列

说实话,CSS attr()全属性支持这个特性我等了六七年至少有了。之前还为其写了个Polyfill工具:“Polyfill吊炸天的CSS attr()新语法

本来以为这辈子都不会看到浏览器对其进行支持了。

万万没想到,Chrome133版本开始居然支持了,它居然支持了。

attr()函数的兼容性

在过去,attr()函数只能用在content属性中,现在所有的CSS属性都支持,而且语法更加丰富,某种程度上,可以颠覆现有的前端开发习惯,一点也不夸张,

二、CSS代码减半,属性为王

有了attr()函数的全支持,那么类似tailwind 的原子类CSS框架都可以退出历史舞台了,因为浏览器原生支持了,相对于回到了过去所有CSS属性都HTML属性设置的年代。

于是,重复样式类名,非重复样式HTML属性外加一点点CSS,开发效率up,开发代码down。

例如之前调整元素之间的间距,可能是这样的CSS原子类:

.m0 { margin: 0; }
.ml0 { margin-left: 0; }
.ml1 { margin-left: .25rem; }
.ml2 { margin-left: .5rem; }
.ml3 { margin-left: .75rem; }
.ml4 { margin-left: 1rem; }
.mt0 { margin-top: 0; }
.mt1 { margin-top: .25rem; }
.mt2 { margin-top: .5rem; }
.mt3 { margin-top: .75rem; }
.mt4 { margin-top: 1rem; }
.mr0 { margin-right: 0; }
.mr1 { margin-right: .25rem; }
.mr2 { margin-right: .5rem; }
.mr3 { margin-right: .75rem; }
.mr4 { margin-right: 1rem; }
.mb0 { margin-bottom: 0; }
.mb1 { margin-bottom: .25rem; }
.mb2 { margin-bottom: .5rem; }
.mb3 { margin-bottom: .75rem; }
.mb4 { margin-bottom: 1rem; }

既啰嗦,又不全,如果是更大的间距,或者是3px,5px这种尺寸就无能为力。

attr()函数全支持之后,那就简单多了:

[m] { margin: attr(m px, 0); }
[ml] { margin-left: attr(ml px, 0); }
[mt] { margin-top: attr(ml px, 0); }
[mr] { margin-right: attr(mr px, 0); }
[mb] { margin-bottom: attr(mb px, 0); }

此时,我们就可以使用自定义的ml,mr这类HTML属性随便定义间距大小了,使用非常方便,例如:

<input><button ml="6">按钮</button>

输入框和按钮之间就有6px的间隙了,截图效果如下所示:

输入框和按钮间隙

类似的还有颜色、背景色、圆角等这类样式的设置:

button {
  --bgcolor: attr(bgcolor type(*), #eee);
  border: 1px solid color-mix(in srgb, var(--bgcolor), black);
  background-color: var(--bgcolor);
  border-radius: attr(radius type(*), 4px);
  padding: .25em .75em;
}
<button bgcolor="skyblue" title="by zhangxinxu(.com)">按钮</button>
<button bgcolor="#00000040" radius="1rem">按钮</button>
<button bgcolor="pink" radius="50%">按钮</button>
<button bgcolor="orange" radius="100% / 50%">按钮</button>

此时的渲染效果如下截图所示:

自定义按钮样式

三、动态URL作为背景图显示

MDN文档上显示,动态URL地址不能使用attr()显示:

Therefore, you can’t use attr() to dynamically construct URLs

<!-- 下面代码是无效的 -->
<span data-icon="https://example.org/icons/question-mark.svg">help</span>
<style>
  span[data-icon] {
    background-image: url(attr(data-icon));
  }
</style>

实际上,是有方法可以显示的,此方法全中国知道的人,目前为止,在我撰写本文之前,估计不超过一双手的人。

那就是使用image-set()函数!

因为image-set()函数是唯一支持字符串作为图片URL的函数。

<a href="https://image.zhangxinxu.com/image/study/s/hanyun.jpg">图片?</a>
<style>
[href$="jpg"]::before { 
  content: ''; 
  display: block; 
  width: 256px; height: 192px; 
  background: image-set(attr(href)); 
  background-size: cover;
}
</style>

此时,在支持的浏览器下面,就会有如下图所示的效果:

很有趣,不是吗?

四、静待全面支持吧

东西肯定是个搞东西,但是浏览器不支持也是白搭。

不过我感觉,Safari和Firefox应该会支持,为什么呢?因为attr()函数的fallback语法他们都已经支持了。

fallback语法兼容性

总之,随着CSS不断发展,CSS这门语言会变得越来越不一样的。

不过问题在于,特性过盛了。

如果基本特性就能满足现有的开发需求,开发人员是没有去学习的动力的,也会阻碍技术本身的普及。

唉,想那么多干嘛呢?

最后,祝温少主在新世界能有好的结局。

温天仁和侍女

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

(本篇完)

你知道吗,输入框的value值也能直接返回数值类型

2025-05-23 00:13:39

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

标题占位符,可以是非字符串吗

一、直接正题-valueAsNumber

我也是最近才知道,原来DOM对象获取属性值,不是都是字符串类型,还可以是数值类型。

已知输入框元素:

<input id="number" min="1" max="10" type="number" />

平常我们获取输入框的值都是使用 number.value 获取的,但是这个属性的返回值是个字符串。

其实现在浏览器支持直接返回数值类型的,使用number.valueAsNumber即可。

实地演示

眼见为实,我们实地测试下,例如typeof下number.valueAsNumber的返回值类型,看看返回的是string还是number.

output.textContent = typeof number.valueAsNumber;

比方说有下面一个数值输入框:

结果是:?

点击上面的按钮,可以看到输出的结果是’number’。

如果是普通输入框?

我们不妨拿<textarea>元素测试下,测试代码如下:

<textarea id="textarea" cols="30" rows="4">10</textarea>
<button onclick="console.log(textarea.valueAsNumber);">点击我</button>

结果是 undefined

说明valueAsNumber属性返回数值不能是普通的输入框元素。

二、valueAsDate属性类似

除了valueAsNumber,还有valueAsDate属性,这个是用在date等与日期相关类型的输入框上的。

返回的是Date对象。

例如下面的实时渲染测试,点击按钮,可以看到返回值类型:

结果是:?

不是所有日期类型都支持

month, date, 以及 week这几个类型的时间选择输入框是支持valueAsDate的,但是datetime-local输入框类型并不支持,因为它表示本地时区中的日期和时间(挂钟时间),但date对象表示绝对时间点。然而,一些浏览器可能提供非标准实现。

例如,我Mac Chrome下测试,返回的就是 null,不支持识别。

<input id="datetime" type="datetime-local">
<button onclick="console.log(datetime.valueAsDate);">点击我</button>

但是,很有意思的,我输出datetime.valueAsNumber反而有值,返回的是当前的时间戳,例如下面的实时渲染测试(选择一个时间,然后点击按钮):

结果是:?

还挺有意思的,我测试了tel类型,返回的是NaN,range类型可以,也就是支持min/max/step这种数值范围计算的输入框是支持valueAsNumber的。

三、结束语

我看了下这两个DOM属性的兼容性,Chrome 5就开始支持了,看来Web领域还有很多我不知道的细节知识,学无止境啊。

可以把相关知识点在《HTML并不简单》这本书中更新下,大家要多多支持这本书,这样才会有第二版。

好吧,就说这么多,又是学习成长的一天。

梅凝压轴

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

(本篇完)