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选择器选择不同类型的先前兄弟元素或父元素。
您可以将其扩展到多个元素
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工作组的一项协作努力,CSS工作组负责监督网络标准。这个想法借鉴了像SASS和LESS这样的CSS预处理器,这些预处理器已经支持嵌套多年。
CSS嵌套模块第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片段根据卡片元素的宽度而不是视口宽度为其设置不同的背景颜色。
基本用法
首先,通过指定容器类型来定义一个容器。这使该元素成为一个容器查询容器。
.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;
}
}
在此示例中,样式被组织成三个层:基础、主题和组件。浏览器按照声明的顺序应用这些层,除非有其他指定。
覆盖层
你可以使用@import规则将外部样式表导入到特定的层中
@layer base;
@import url("base-styles.css") layer(base);
@import url("theme.css") layer(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/