CSS正在不断发展,跟随本简单指南一起进化您的代码
我喜欢某些技术能够感知周围发生的事情,并据此转变方向,通过尝试与周围年轻的技术人员做同样的事情,来使自己的技术更加出色,带来新的生机。
JavaScript被各种库和框架包围,扩展了其潜力,然后纯JavaScript吸收了许多这些想法并飞跃发展。曾经jQuery是加速开发的必需品,现在像https://youmightnotneedjquery.com/这样的网站
CSS的世界也是如此。像LESS、Sass、SCSS和Stylus这样的技术成长起来以扩展CSS的能力:但CSS不是一个静态资源,它已经采纳了它们提供的许多改进并将其纳入其核心。
让我们来看看一些最近的CSS变化,看看我们是否可以利用这些新选择器来扩展自己的能力。
:has()选择器 -
CSS :has()选择器代表了在样式能力方面的一大飞跃。它允许开发人员根据是否存在匹配给定条件的后代元素来样式化元素。
这个特性增强了CSS的选择性和动态性,无需额外的JavaScript!
:has()伪类选择器如果传递给它的相对选择器中的任何一个至少匹配这个元素的一个元素时,会选择一个元素。
它通过将一个相对选择器列表作为参数来提供选择父元素或与参考元素相关的前一个兄弟元素的方法。
使用:has()可以在样式表中直接实现复杂的样式场景。
这对于根据内容结构设计响应式界面和增强用户交互非常有用。
随着CSS的不断发展,:has()的引入为其他高级功能铺平了道路,促进了更直观和灵活的网页设计实践。
以下是一个使用CSS :has()选择器的简短代码示例
/* Styles the <li> only if it contains a link with the class .active */
li:has(a.active) {
background-color: lightblue;
}
这个片段演示了如何使用:has()根据其他元素中存在某些元素来有条件地应用样式,从而增强CSS选择器的动态性和特异性。
这里还有一个简单的例子
/* Selects an <h1> heading with a <p> element that immediately follows the <h1> and applies the style to <h1> */
h1:has(+ p) {
margin-bottom: 0;
}
The :has() pseudo-class takes on the specificity of the most specific selector in its arguments, similar to :is() and :not().
局限性
- 如果浏览器不支持 :has(),则整个选择器块将失败,除非它位于一个宽容的选择器列表中,如 :is() 或 :where()。
- :has() 不能嵌套在另一个 :has() 中,因为可能会发生循环查询。
- 伪元素不是 :has() 中的有效选择器,并且伪元素不能作为 :has() 的锚点。
考虑以下 HTML 片段
<section>
<article>
<h1>Morning Times</h1>
<p>Lorem ipsum dolor sit amet...</p>
</article>
<article>
<h1>Morning Times</h1>
<h2>Delivering you news every morning</h2>
<p>Lorem ipsum dolor sit amet...</p>
</article>
</section>
以下 CSS 规则选择紧接在
元素后面的 元素(由相邻兄弟组合符 + 指示)
h1:has(+ h2) {
margin: 0 0 0.25rem 0;
}
h1:has(+ h2) {
margin: 0 0 0.25rem 0;
}
没有 :has(),您无法使用 CSS 选择器选择不同类型的 preceding sibling 或父元素。
可以将其扩展到多个元素
h1:has(+ h2, + p) {
/* Styles for h1 followed by h2 or p */
}
有关更多示例和兼容性详细信息,请查看 https://caniuse.cn/css-has。
CSS 嵌套 - 保持整洁
CSS 嵌套代表了重大进步,通过允许选择器彼此嵌套,使得样式表更加结构化和高效。
该功能简化了复杂样式表的管理,并提高了可读性。
CSS 嵌套允许您在其他 CSS 规则内部编写 CSS 规则。这有助于将样式限定为 HTML 结构的特定部分,使 CSS 更易于维护和阅读。以下是一个示例
article {
color: black;
background-color: white;
h2 {
font-size: 1.5em;
}
p {
font-size: 1em;
&.lead {
font-weight: bold;
}
}
@media (max-width: 600px) {
background-color: #eee;
h2, p {
text-align: center;
}
}
}
在这个示例中,h2 和 p 样式嵌套在 article 中,仅当它们是 article 的后代时才应用。
在嵌套块中使用的 & 符号用于引用主选择器,允许进行更复杂的选择,如 p 上的 .lead 类。
您可能遇到过 @media 规则,它们是嵌套 CSS 的完美示例,但您知道您还可以创建其他嵌套块吗?
CSS 嵌套的历史背景
CSS 嵌套的开发是由 W3C(万维网联盟)的一部分 CSS 工作组协作完成的,该工作组负责监督网络标准。这个想法借鉴了 SASS 和 LESS 等CSS预处理器多年的嵌套支持。
CSS Nesting Module Level 1 引入了 CSS 中的原生嵌套,旨在将这个流行的功能直接带入浏览器,以便创建更直接、更易于阅读的样式表。
在嵌套块中使用 & 符号来引用父选择器,这对于根据父子关系应用样式或根据子条件修改父元素至关重要。
建议使用 & 符号以提高清晰度和特定性,特别是在处理伪类、修饰符或嵌套样式依赖于父状态或结构时。
优势
使用 CSS 嵌套提供了几个优势,包括通过允许相关样式分组在一起来提高可读性和组织性。它减少了重复选择器的需求,使样式表更易于维护和简洁。这种结构反映了 HTML 结构,使理解样式和文档元素之间的关系更容易。此外,嵌套可以导致更高效的样式工作流程,特别是在处理复杂布局或基于组件的设计时。
有关最新的支持和使用详细信息,请查看 https://caniuse.cn/css-nesting
与嵌套相关的较新的 CSS 想法包括在样式表中实现更直观的条件和增强样式的作用域管理,这可能导致 CSS 设计在模块化和组件化方面的更先进的方法。
CSS text-wrap: balance - 使文本更容易阅读
CSS text-wrap: balance 属性是对网络上更美观文本布局需求的响应。
历史上,实现平衡的文本块需要手动调整或复杂的脚本。
该属性旨在自动化文本块内行长度的平衡,使文本在行之间分布得更均匀。这代表了将传统排版原则(平衡的文本对于可读性和视觉吸引力至关重要)引入网页设计的努力。
该功能是CSS中持续开发的一部分,旨在增强文本布局能力。
例如
p {
text-wrap: balance;
}
应谨慎使用CSS的text-wrap: balance属性。
在需要精确控制文本布局的情况下避免使用它,因为它旨在达到可能不适合每个设计需求的平衡。
它对于较长的文本块来说不太合适,因为传统的换行可能足以保持可读性。
此外,考虑在复杂布局或大量文本上无差别应用时对性能的影响,因为平衡可能会影响渲染速度。
有关最新支持和使用详情,请查看https://caniuse.cn/css-text-wrap-balance
容器查询
容器查询代表了CSS的显著进步,它使组件能够根据它们自己的大小而不是视口的大小来自定义样式。此功能特别适用于创建更灵活地适应不同容器的响应式设计。
例如,您可以编写
.card {
container-type: inline-size;
}
.card:container(width >= 500px) {
background: lightblue;
}
.card:container(width < 500px) {
background: lavender;
}
此CSS代码片段使.card元素根据其宽度而不是视口宽度具有不同的背景颜色。
基本用法
首先,通过指定container-type定义一个容器。这使得该元素成为容器查询容器。
.container {
container-type: inline-size;
}
然后,使用@container根据容器的大小应用样式
@container (min-width: 500px) {
.box {
background: lightblue;
padding: 2rem;
}
}
@container (max-width: 499px) {
.box {
background: lavender;
padding: 1rem;
}
}
高级示例:卡片组件
想象一个根据其大小改变布局的卡片组件
.card {
container-type: inline-size;
}
.card:container(width >= 600px) {
display: flex;
gap: 20px;
}
.card img {
max-width: 100%;
height: auto;
}
@container (min-width: 600px) {
.card-content {
flex: 1;
}
}
此设置允许.card组件在宽度至少为600px时从垂直布局切换到水平布局,提供更灵活和响应式的设计。
具有容器查询的响应式网格
容器查询也可以用于创建不仅基于视口还基于容器宽度的响应式网格
.grid {
container-type: inline-size;
display: grid;
}
@container (min-width: 500px) {
.grid {
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}
}
@container (min-width: 800px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
此示例演示了网格布局如何根据容器宽度动态调整其列,增强了基于网格的设计的适应性。
容器查询和宽高比
容器查询可以与aspect-ratio属性结合使用,以在容器大小不同的情况下创建保持特定宽高比的元素
.aspect-ratio-box {
container-type: inline-size;
aspect-ratio: 16 / 9;
background: lightcoral;
}
@container (min-width: 400px) {
.aspect-ratio-box {
aspect-ratio: 4 / 3;
}
}
此代码片段根据容器宽度调整.aspect-ratio-box的宽高比,展示了容器查询在管理响应式宽高比方面的灵活性。
要检查容器查询当前浏览器支持情况,请查看https://caniuse.cn/css-container-queries。
展望未来,与容器查询相关的开发可能包括对容器上下文的更精细控制或与Grid或Flexbox等其他布局模型集成,从而增强响应式设计的工具集。
@Layer - 管理您的样式
CSS的@layer规则是网页设计领域的一项新进展,旨在改进样式表的编管、组织和应用方式。
此新功能引入了一种明确定义样式层的方法,从而允许CSS规则的简单级联,避免冲突。
理解@layer规则
@layer规则使开发者能够将CSS规则分组到不同的层中。这些层遵循特定的顺序,当冲突发生时,浏览器会根据这个顺序确定哪些样式优先。这种方法简化了复杂样式的管理,特别是在大型项目或集成第三方样式时。
@layer规则的用法
您可以声明一个层,然后添加样式如下
@layer base {
body {
font-family: sans-serif;
line-height: 1.6;
}
}
@layer themes {
.dark-mode {
background-color: #333;
color: #fff;
}
}
@layer components {
.button {
padding: 10px 15px;
border-radius: 5px;
}
}
在此示例中,样式被组织为三个层:base、themes和components。浏览器按声明的顺序应用这些层,除非指定了其他顺序。
覆盖层
您可以使用@import规则将外部样式表导入到特定的层中
@layer base;
@import url("base-styles.css") layer(base);
@import url("theme.css") layer(themes);
此代码将外部样式导入到base和themes层,确保级联遵循预期的顺序。
层顺序
使用@layer规则和多个层显式控制层的顺序
@layer reset, base, themes, components;
此声明设置了层的级联顺序,无论它们在CSS中定义的位置如何。
浏览器支持
要检查当前浏览器对容器查询的支持,请访问https://caniuse.cn/css-cascade-layers。
未来方向
引入@layer规则为管理样式表复杂性和提升性能开辟了新的可能性。未来的CSS提案可能会在此基础上,通过引入对层交互的更精细的控制,或者将层与CSS框架和方法更深入地集成来实现。
CSS是一种不断发展的语言,几年前无法实现,需要第三方尝试来解决其缺陷的内容,现在变得可能且易于实现。回顾我们自己的代码和样式,看看我们是否可以现代化我们的网站,将给我们所有人带来收益。
在Joomla社区杂志上发表的一些文章代表了作者对特定主题的个人意见或经验,可能并不与Joomla项目的官方立场一致。
通过接受,您将访问由 https://magazine.joomla.net.cn/ 外部的第三方提供的服务
评论 4
你好,
你真的确定关于.card:container的东西吗?这将是一个很酷的功能,但我在文档中没看到任何地方提到它,并且它不能与FF一起工作。
谢谢
你提出的是一个有趣的观点。
我从Firefox的角度进行了检查,并找到了这篇文章
https://mdn.org.cn/en-US/docs/Web/CSS/CSS_containment/Container_queries
我还没有时间进行测试,但我会看看是否需要修改文章。感谢你的评论;这些都帮助我改进并做得更好。
这不是一个有趣的观点:关于容器的部分是错误的。你必须为你的 .card 使用容器,.card:container 语法不存在。你在发布代码之前测试过吗?
现代CSS的全面回顾
https://frontendmasters.com/blog/what-you-need-to-know-about-modern-css-spring-2024-edition/