MoreRSS

site iconZhangXinXu | 张鑫旭修改

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

Inoreader Feedly Follow Feedbin Local Reader

ZhangXinXu | 张鑫旭的 RSS 预览

Nice!继text-wrap之后,Flex布局也支持balance排版了

2026-10-14 18:24:41

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

一、内联balance排版

3年前有介绍过内联元素的balance排版,就是使用text-wrap:balance声明,很好用,我已经在真实项目中使用了。

可以让居中排版的多行元素每一行的数量尽可能均衡,使视觉效果更好。

balance排版效果示意

眼见为实,您可以狠狠地点击这里:text-wrap:balance实现头像均衡布局demo

目前所有主流浏览器都已经支持,可以放心大胆使用,就算浏览器不支持,也仅仅是传统排版效果而已。

兼容性

更多信息可以访问这里:快速了解text-wrap:balance的作用

好消息!

现在不仅内联元素,块级元素也支持balance排版了,那就是flex-wrap: balance。

二、flex布局balance排版

Flex布局实现balance排版很简单,只需要将传统的flex-wrap:wrap声明替换为flex-wrap:balance就可以了。

来看下效果对比,默认wrap排版会优先前排的宽度,直到宽度放不小,才会换行显示,比方说这般:

默认 wrap 排版示意

如何选择balance排版,则每一行的标签数量会尽可能的均等,于是排版布局效果就会是这样的:

balance排版效果示意

眼见为实,您可以狠狠地点击这里:flex-wrap:balance与Flex布局均衡排版demo

三、flex-line-count指定均衡行数

默认情况下的均衡排版会充分利用容器宽度。

实际上,Flex布局提供了能力,可以指定均衡排版的行数,就是使用flex-line-count属性。

例如:

.container {
  display: flex;
  flex-wrap: balance;
  flex-line-count: 3;
}

那么书籍标签就会三行显示,每行均分两个标签,效果如下图所示:

三行均衡排版效果示意

衍生作用

指定flex-line-count的数量后,我们其实可以很方便的在Flex布局中实现瀑布流布局效果。

指定Flex容器为垂直排版,设置flex-line-count为固定的列表值,此时,无论Flex子项的数量多少,都会瀑布一样的方式往下排版。

大家不妨想想一下上面三行均衡排版图旋转90°之后的效果,如果列表项足够多,是不是就是瀑布流排版呢?

具体示例我就不放出来了,AI时代,大家知道有这么回事就好了。

或者看下面的示意脑补下吧,

瀑布流布局示意

四、兼容性以及若干碎碎念

Flex布局的balance排版的兼容性如下:

balance Flex布局中兼容性

虽然看起来Chrome 150才支持,但并不影响我们的使用,因为某种意义上,此特性是渐进增强特性。

.container {
  display: flex;
  flex-wrap: wrap;
  flex-wrap: balance;
}

如果浏览器支持,那就是balance排版,如果不支持,还保持现在的wrap排版,并不会造成显著的影响。

碎碎念时间

最近突然冒出了个step-5的模型,最近CodeBuddy和WorkBuddy中限免,试用了下,除了思考慢了点,最终效果还可以。

是一家名叫阶跃星辰 – stepFun的公司开发的,以前听都没听过,突然冒出来的,还真是有趣。

说不定什么时候,某个会自学习的AI模型是从其他模型公司突然涌现。

木卫二

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

(本篇完)

Document Picture-in-Picture API与任意元素画中画实现

2026-10-08 18:38:55

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

一、温故而知新

画中画的实现这个2018年的时候就有介绍,乖乖,已经是8年前了,不过那个时候只支持视频元素,可以访问这里了解:video视频播放Picture-in-Picture画中画技术

现在,不仅是视频元素,其他普通元素现在也支持画中画的能力了,就是使用documentPictureInPicture.requestWindow()方法。

在AI时代,我们无需关心具体的API细节。

因此,我不打算介绍各种方法参数,直接上案例。

您可以狠狠地点击这里:普通元素画中画呈现效果demo

点击如下图所示的按钮,就可以看到图片元素的小窗口在显示器的右下方了,即使浏览器最小化,此窗口依然存在。

demo点击画中画按钮示意

进入画中画状态后

之所以进入画中画状态后,背景色从深色变成浅色,是因为加入了@media (display-mode: picture-in-picture)的测试代码。

如下所示:

figure {
    background-color: #333;
    color: #fff;
}
@media (display-mode: picture-in-picture) {
    figure {
        background-color: #f5f5f5;
        color: #333;
    }
}

二、完整代码示意

先看下HTML结构,一个提示元素,一个主体展示元素:

<p id="inPicMsg" hidden>图片信息元素处于画中画状态。</p>
<figure>
    <img src="hanyun.jpg" alt="张含韵">
    <figcaption>画面中这人是谁?</figcaption>
</figure>

<button id="inPicBtn" type="primary" class="ui-button">进入画中画</button>

关键还是交互部分,如下所示:

const figure = document.querySelector("figure");
// 进入按钮和进入提示元素
const inPicBtn = document.getElementById("inPicBtn");
const inPicMsg = document.getElementById("inPicMsg");

inPicBtn.addEventListener("click", function () {
    window.documentPictureInPicture.requestWindow({
        width: figure.clientWidth + 32,
        height: figure.clientHeight + 72,
    }).then(pipWindow => {
        // 添加关闭处理
        pipWindow.addEventListener("pagehide", (event) => {
            inPicMsg.hidden = true;
            inPicMsg.after(figure);
        });
        // 显示提示
        inPicMsg.hidden = false;
        // 创建渲染样式
        const style = pipWindow.document.createElement("style");
        fetch(document.querySelector("link[href^='http']").href)
          .then(response => response.text())
          .then(text => {
            style.textContent = text;
          });
        pipWindow.document.head.append(style, document.querySelector("style").cloneNode(true));
        // 添加目标元素
        pipWindow.document.body.appendChild(figure);
    });
}, false);

// 创建退出按钮
documentPictureInPicture.addEventListener("enter", (event) => {
  const pipWindow = event.window;

  const pipExitButton = pipWindow.document.createElement("button");
  pipExitButton.className = "ui-button";
  pipExitButton.type = "primary";
  pipExitButton.textContent = "退出画中画";
  pipExitButton.addEventListener("click", () => {
    window.documentPictureInPicture.window.close();
  });

  pipWindow.document.body.append(pipExitButton);
});

这段代码处理示意了画中画模式的进入退出,还演示了如何在画中画窗口创建额外的元素以及构建样式。

需要注意的是,我原本打算插入<link>元素,直接链接一个CSS文件,结果发现无效,于是改为fetch CSS数据,使用<style>元素内联实现的。

以及,实际开发的时候,可以使用 async/await 语法减少Promise的嵌套使用。

三、就这些,没什么好说的

画中画的实现其实就那几行代码,然后,画中画小窗口的关闭按钮这些都是可以自定义的,如何自定义使用,到时候让AI模型帮你处理就好了,我就不告诉大家是disallowReturnToOpener这个可选参数了。

接下来,看下兼容性:

画中画API兼容性

Safari浏览器拖了后腿,不过桌面端本身就是Chrome的天下,因此,此特性还是可以大胆使用的,毕竟,就算浏览器不支持,也支持保持现状而已。

好了,就说这么多,博闻强识。

对了,今年开春到现在,都是博客和B站的碎片化输出,打算国庆后到春节前,弄一个前端在线学习的系列课,当然,要与时俱进,不然狗都不看。

拭目以待吧~

拭目以待

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

(本篇完)

一个视频彻底看懂CSS scroll-axis-lock none的作用

2026-09-30 17:05:03

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

一、一句话概述

scroll-axis-lock 是 CSS Overflow Module Level 5 的新属性,用来控制浏览器是否自动把滚动手势锁定到单一坐标轴。

什么意思呢?

就是说,scroll-axis-lock可以控制用户触摸/拖拽滚动时,是否忽略微小位移。

比方说一个既能水平滚动,又能垂直滚动的容器。

在默认的浏览器行为中,用户向下滚动的时候,毕竟是手动操作,水平方向难免会有微小的位置变化,此时,浏览器会触发轴锁定,会忽略水平方向的位移,让页面以一条直线的方式保持滚动。

这在常规的网页浏览中是极好的体验优化,可以避免手滑带来的斜向漂移。

但是,在地图、画布、大图查看器这类场景,用户就是需要斜向双轴同时滚动,这个默认行为就会干扰。

所以,就需要scroll-axis-lock:none来关闭这种单轴锁定。

我们可以通过下面的视频对比出两者的效果区别(点击播放):

二、语法、兼容性以及其他

scroll-axis-lock属性的语法如下。

auto(初始默认值)
浏览器启用轴锁定启发规则。手势偏向某一轴时,会抹掉另一轴微小滚动量,只单轴滚动。
.scroller {
  scroll-axis-lock: auto;
}
none
关闭浏览器的轴锁定。允许同时水平+垂直双向滚动,不管手势角度,X、Y方向位移全部生效,不会被浏览器过滤掉另一轴增量。
.map-canvas {
  overflow: scroll;
  scroll-axis-lock: none;
}

兼容性

scroll-axis-lock是个非常新的CSS特性,目前只有Chrome浏览器支持,具体如下图所示:

scroll-axis-lock兼容性

不过,scroll-axis-lock属性本就是一个渐进增强的特性,因此,完全不影响我们在浏览器中使用。

浏览器支持体验更好,如果不支持,那就保持现状。

和overscroll-behavior的关系

overscroll-behavior属性也与滚动行为密切相关,只不过overscroll-behavior 控制滚动到边界之后的行为;scroll-axis-lock 控制滚动过程中是否过滤另一轴滚动增量。
以及scroll-axis-lock属性只作用于手势滚动(触摸、鼠标拖拽),不影响鼠标滚轮,滚轮不受这个属性控制。

overscroll-behavior属性也是比较实用的一个属性,可以关闭Mac系统下默认的滚动边界回弹行为,以及关闭滚动左滑到底后触发返回上一页的默认行为。

具体可以访问我之前这篇文章:CSS overscroll-behavior让滚动嵌套时父滚动不触发

三、哎呀,居然食言了

本以为上一篇文章是国庆节前最后一篇文章,结果这一篇才是。

因为八成的同事都请假了(可以连休13天),我一个人在公司,实在没有需求,那就写文章代替摸鱼吧,桀桀桀。

好了,其他就不多说了。

大家祝我国庆节继续爆护吧!

分享下最近一个月作钓鱼获。
图一:浦东梅林垂钓园,168六小时,约莫30斤不到点,大口鲶,昂刺鱼和红鲳
图二:浦东清水湾垂钓,120四小时,去的晚,约莫十七八斤,鲤鲫和鳊鱼
图三:浦东繁茂垂钓,238六小时,草鱼鳊鱼红鲳,约莫70斤
图四:嘉定痴渔户外营地垂钓,68元5小时,强回,最终57.6斤,差4两上岸
图五:奉贤兄弟垂钓,180五小时,回鱼3元每斤,最终72斤,上岸小盘
图六:青浦庆同钓场,198五小时,鱼获35斤多,大鳊鱼大板鲫

渔获

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

(本篇完)

独家:CSS背景色单方向扩展技术

2026-09-29 11:31:56

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

一、前言

背景色扩展我们可以使用outline或者box-shadow属性,但是,如果希望是单个方向的扩展,同时不影响现有布局,该如何实现呢?

比方说下面这个使用场景,底部区域sticky粘性定位。

但是由于外部容器设置了padding,导致会有内容从底部区域穿透出来,看起来体验就不怎么好。

问题示意GIF

比较常用的方法是设置margin负值 + padding值修正。

但这种方法并不怎么优雅,最简单的办法其实就是背景色区域扩展出去,直接覆盖就好了。

不过这里并非四面扩展,outline属性并不支持方位设置。

此时,border-shape和border-image属性就是更好的选择。

二、border-shape单向扩展

核心代码:

.breakout-background {
  border-shape: inset(0 -16px -16px) circle(0);
  border-color:skyblue;
}

此时的底部布局和交互效果就会是下图GIF这般所示:

底部背景色扩展效果示意

相关代码如下:

<aside>
  <main>
    内容<br>内容...
  </main>
  <footer>
    底部
  </footer>
</aside>
aside {
  padding: 16px;
  border: 1px solid #ccc;
  background: aliceblue;
  width: 300px; height: 200px;
  overflow: auto;
  overscroll-behavior: none;
  main {
    height: 300px;
  }
}
footer {
  padding-top: 10px;
  position: sticky;
  bottom: 0;
  background: skyblue;  /* 兜底,非必须 */
  border-shape: inset(0 -16px -16px) circle(0);
  border-color: skyblue;
}

释义

CSS border-shape 属性接受两个形状值,前者表示外部形状,后者表示内部形状。

inset() 函数是 CSS Shapes 图形相关的基础形状函数,用来创建内凹矩形裁剪区域。

inset(top right bottom left round radius);

其中,top right bottom left表示的是四个方向向内收缩的距离,注意,是内缩的距离,支持简写,简写规则和 margin /padding 一致。

这里,inset(0 -16px -16px)中的值是负数,因此,形状是外扩,而非内缩,扩展方向是左右和底部。

于是,可以正好覆盖外部容器设置的16px padding大小。

circle(0)表示的是内部形状,表示一个放置在中心的零半径圆。

零半径圆等于没有图形,作用是保证外部形状可以连内部也完全填充。

所以,上述代码中的background: skyblue其实是可以删除的。

关于border-shape

border-shape是个很实用的新特性,我三个月前就介绍过了,有兴趣访问这里了解:全新的CSS border-shape属性简介

我看了下,三个月过去了,目前还是仅Chrome浏览器支持。

border-shape 9月份兼容性

所以,从实战角度考虑,我们必须考虑其他兼容性更好的方法,那就是border-image属性。

三、传统方法border-image

border-image扩展元素的图形区域,这个我很多年前就介绍过,包括我的著作《CSS新世界》中也有详细介绍,是CSS里面极为罕见的不影响排版情况下拓展元素的渲染区域的属性。

唯一的问题就是语法复杂了些,不过现在有AI了,大家只要知道border-image可以做这样的事情,然后让AI去处理就好了。

详见此文:被低估的border-image属性

在本例中,想要扩展元素左右和下方的背景色,可以这么设置。

footer {
  border-image: conic-gradient(skyblue) fill 0//0 16px 16px;
}

如果你想装逼,也可以使用image()函数。

image()函数也是个新特性,原本的语法支持URL图像外加剪裁,例如:

image("image1.jpg#xywh=40,0,20,20")

我实际测下来,目前仅支持背景色,Chrome和Firefox浏览器都支持,Safari不支持。

至于具体的兼容性数据,我并没有找到。

代码使用示意:

footer {
  border-image: image(skyblue) fill 0//0 16px 16px;
}

效果是一样的。

底部背景色扩展效果示意

四、结语

总结一下,目前任意方向背景色扩展技术,可以在生产环境放心使用的还是border-image属性。

conic-gradient是锥形渐变,也是非常实用的渐变,可以用来绘制饼图,loading图形或者棋盘网格,详见此文:CSS conic-gradient()锥形渐变简介

不过很多开发人员对锥形渐变掌握并不熟,这里替换成线性渐变也是可以的,参考如下:

footer {
  border-image: linear-gradient(skyblue) fill 0//0 16px 16px;
}

注意,conic-gradient(skyblue)和linear-gradient(skyblue)模拟纯色背景的语法一开始不是这么精简的,如果你的项目对兼容性要求比较高,稳妥期间,还是使用完整写法conic-gradient(skyblue 0 0)和linear-gradient(skyblue, skyblue)。

好了,其他就没什么了,这应该是国庆节前的最后一篇文章了,祝大家国庆节快乐。

唉,又是一年国庆了,一年又一年,时间过得太快了。

就这样吧,我们下篇文章再见。

再见

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

(本篇完)

CSS rex、rlh、ric等根家族单位简介

2026-09-17 19:42:29

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

一、从rem单位说开去

说起CSS根单位,大家最熟悉的莫过于 rem 单位。

从IE9浏览器就开始支持。

是目前CSS领域最常用的CSS单位之一,尤其在移动端的弹性布局中。

很多人不知道的是,从Chrome 111(2023年3月)、Safari 16.4(2023年3月)、Firefox 120(2023年11月)开始,还支持了其他一系列的根元素单位,五花八门,将目前基于所有与文字相关的CSS相对单位都囊括了。

具体参见:

rcap

等于根元素字体字号对应的“大写字母的高度”。

CSS的cap是个比较晚支持的CSS单位,中文场景下此单位出场机会不大,因为表示的是英文大写字母的高度。

其兼容性如下(单位cap和rcap兼容性一致):

rcap单位兼容性

rch
ch表示字符0的宽度,自然,rch就表示当前根元素数字0,Unicode字符 U+0030的宽度。

ch是个IE时代的CSS单位,但是rch却比rlh支持的晚,Safari 17.2(2023年12月)、Firefox 147(2026年1月)才支持.

rch的兼容性

rem

代表根元素(通常是 <html>)的 font-size。在根元素的 font-size 属性内使用时,代表其初始值。浏览器常见默认值为 16px,但用户设置可能改变该值。

rex
等于根元素 font 的 x-height(小写字母x高度)。

rex的兼容性和rch是一样的。

ric
ic这个单位我之前也介绍过,这是与中文环境,东亚语言密切相关的CSS单位。表示字符“水”所占据的宽度。中文字体几乎都是等宽,因此,这个单位可以预估一段纯中文字体占据的宽度。

ric自然就表示根元素字体上“水”这个字符占据的宽度了。

单位ic是2022年各大浏览器开始大规模支持的,目前算是一个可以放心使用的单位了。

ic单位兼容性

至于单位ric的兼容性,则和rex他们一致。

rlh
CSS lh和rlh都是新CSS单位,与行高的计算值相关。

然后出乎意料的,lh虽然是新单位,但是rlh的兼容性却比rex、rch这些老单位的根元素表示要好。

rlh单位兼容性

二、根字体单位实战案例

苦思冥想,想不到什么好的实战案例。

突然想到了一个办法,问AI。

这是AI提供的案例:

html {
  font-family: system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.6;
}
/* 标题:上下内边距跟随大写字母高度 */
h1 {
  padding-block: 1rcap;
}
/* 正文行内图标,高度匹配小写x高度 */
.inline-icon {
  height: 1rex;
}
/* 6位数字验证码输入框 */
.code-input {
  width: 6rch;
}
/* 中文评论框,最多容纳20个汉字 */
.cn-input {
  width: 20ric;
}
/* 段落间距,基于根行高,全局垂直韵律 */
p {
  margin-block: 1.5rlh;
}

嗯……怎么说呢?感谢都是非root根元素单位的应用场景。

算了算了,大家了解下吧,至少下次看到这些单位知道是什么意思吧。

三、就这么结束啦

关于CSS新单位,几个月前也介绍了一波,有兴趣可以访问“CSS新单位dvh、lvmin、vi、cqb等初解”这里了解。

虽然出了很多CSS新单位,但由于目前的CSS单位够用了,且这些单位大都不是必须不可替代的。

因此,大多都无人问津。

有没有展开介绍的必要。

就这样吧,我们下个视频再见。

再见

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

(本篇完)