值得信赖、功能强大且稳定的 CSS,可立即使用。
我认为,每位前端开发者都应该了解 :has() 不仅仅是“父选择器”,还应该了解 subgrid 的使用方式和原因、如何使用内置 CSS 语法进行嵌套、如何让浏览器平衡标题文本换行,以及如何使用容器查询单位。
本文是去年发布的“2023 年所有前端开发者不可不知的 6 个 CSS 代码段”的续篇。
CSS:has(.potential-beyond-being-a-parent-selector)
:has()
:has() 已于 2023 年底在所有主流浏览器中推出!这个新选择器看起来很小,似乎没什么特别之处,但您会惊讶地发现,它能解锁许多用例:游戏、反应性、内容感知布局、智能组件,以及 Jhey 在这篇文章中深入探讨的更多用例。
以下是使用 :has() 作为父选择器的几个示例。之所以取这个名称,是因为选择器的主题通常位于末尾,例如 ul li,其中 li 是主题并获取样式。使用 :has(),选择器开头的元素可以成为主题。在以下示例中,如果按钮内有类为 .icon 的元素,则按钮会留出间距。如果卡片内有图片,则卡片会改变方向。
button:has(.icon) {
gap: 1ch;
}
.card:has(img) {
grid-auto-flow: row;
}
一个长期以来备受期待的选择器是根据布局中的项数来更改布局。现在,借助 :has(),您可以将容器作为正文,同时查询子项的数量。
main:has(> :nth-child(5)) {…}
再举一个更高级别的示例,当网页上的特定复选框处于启用状态时,更改整个文档中设置的样式:
html:has(#dark-mode:checked) {…}
这些都是简单的使用情形,不会更改选择器的对象。如果您只看这样的示例,可能会认为 :has() 仅限于作为父选择器。不过,请参考以下示例。这些选择器会基于共同的祖先检查某些内容,然后将选择器主题旋转到页面中更深处的某个子级。
此示例展示了当任何输入无效时,如何显示表单错误元素:
form:has(:user-invalid) .error {
display: block;
}
以下示例会在侧边栏具有 .--is-open 类时滑出主内容区域:
html:has(#sidenav.--is-open) main {
translate: -320px;
}
下面是一个有趣的演示,其中使用 :has() 作为父级选择器、:has()(带有数量查询)和容器查询来制作网格布局,该布局能够以优雅的方式在竖屏或横屏方向上显示 1-12 个元素:
创建子网格
subgrid
多年来,前端 Web 社区一直要求使用子网格来完善和完成广受欢迎且功能强大的 CSS 网格布局引擎。 现在,该功能已在所有三大主流引擎中提供。
如果您想了解概览,请点击此处详细了解子网格。
body {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(30ch, 1fr));
> article {
display: grid;
grid-row: span 4;
grid-template-rows: subgrid;
}
}
以 CSS 方式嵌套
nesting
内置 CSS 嵌套功能已于 2023 年在所有主流浏览器中推出。 我甚至更新了网站,移除了编译嵌套的构建流程,现在可以发布更小的样式表了!没错,采用嵌套的样式表更小,并且所有浏览器开发者工具都已准备好表示它。
如需查看 CSS 嵌套语法概述,请点击此处了解所有详情。以下代码示例展示了一个语法示例。
.you {
.can-totally-ship-this {
&.if-you-wanted {
/* it's VERY MUCH like SCSS */
&:is(:hover, :focus-visible) {
/* put a bird on it */
}
}
}
}
.for-theming {
@media (prefers-color-scheme: dark) {
/* you can nest media queries */
}
}
/* or for theming with [data-theme="dark"] */
.button {
background: black;
color: white;
/* nest and do more than just append, flip it and reverse it */
[data-theme="dark"] & {
background: white;
color: black;
}
}
让浏览器平衡标题
balance
pretty
如果没有 text-wrap: balance,开发者和文案撰写者只能依靠换行提示(例如 <wbr> 元素或 ­)。这在很大程度上是一场必败的战役,因为一旦内容被翻译、缩放或以任何方式修改,就无法保证这些换行提示会出现在新内容呈现的正确位置。
借助平衡的文本换行,您可以将这项工作交给浏览器。您可以在以下 Codepen 中查看比较结果。
使用容器查询单元
cqw
去年的博文建议每位前端开发者都应了解如何编写容器查询。如果您尚未学习,不妨在 2024 年尝试一下,并了解一下容器查询单位。概而言之,Ahmad Shadeed 在 2021 年撰写了一篇关于容器查询单位的精彩文章。
新增了 6 个容器查询单位:container query 单位:
- 内嵌变体
cqi。 - 宽度变体
cqw。 - 块变体
cqb。 - 高度变体
cqh。 - 长度较短的变体
cqmin。 - 长度较长的变体
cqmax。
考虑一个相对动画和固有动画应用于容器的场景。 使用 100cqi(即容器内嵌大小的 100%)从容器中完全滑出的子元素。
@keyframes slide-out-of-container {
to {
translate: -100cqi;
}
}
以下是一个卡片,其中包含容器自适应排版,以及可根据容器方向调整大小的图片,如果方向为横向,则图片会变为一半大小。
.card {
:is(h2,h3) {
font-size: clamp(1.5rem, 5cqi, 4rem);
}
img {
inline-size: 100cqi;
@container (orientation: landscape) {
inline-size: 50cqi;
}
}
}
如果您不熟悉这些单元,建议您查看 2024 年提供的所有单元。