本文最后更新于 2025年1月7日 上午
align-centent
革新
以前,居中元素需要使用各种方法,比如 Flexbox 属性、margin 甚至绝对定位。这意味着开发者需要花费大量时间进行调整和尝试,最终结果可能在某些屏幕尺寸或浏览器类型下失效。
align-content
属性的美妙之处在于它的简洁性。你无需手动将所有元素包裹在容器 div 中,也无需费力地解读复杂的 Flexbox 选项。只需要在你的元素上使用这个属性,它就能根据父容器的显示模式自动进行对齐。
这个新属性对于响应式设计来说是一场革命。它能在任何屏幕尺寸上实现完美的居中对齐,无需额外的媒体查询或布局调整。这意味着“更少的代码,更好的性能,以及更少的样式系统潜在故障点。”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| .old-center { display: flex; justify-content: center; align-items: center; min-height: 100vh; }
.new-center { align-content: center; min-height: 100vh; }
.center-text { align-content: center; }
.center-group { align-content: center; gap: 1rem; }
|
@property
的威力:类型安全的 CSS 变量
CSS
变量(自定义属性)已经存在一段时间了,但它们有一个局限性:浏览器总是将其值解释为字符串。新的 @property
规则(CSS Houdini
的一部分)解决了这个问题,使得可缩放矢量图形 (SVG) 更加强大。
在使用普通的 CSS
变量时,动画和过渡可能存在问题或根本无法实现,因为浏览器无法理解变量的类型。例如,我尝试动画化一个基于百分比的渐变,但这行不通,因为对于浏览器来说,它只是一个字符串,而不是一个数字。
@property
规则通过指定变量的类型来消除这个限制。这意味着你的网站将拥有更流畅的界面、更具响应性的功能,以及更少的样式表异常行为。想象一下,为你的 CSS
带来类型安全,就像你在 JavaScript
中使用 TypeScript
一样。
仅仅是构思一个主题系统,在不同模式之间切换时能够实现颜色混合,就令人兴奋不已。这样,你可以定义浏览器可以原生识别的颜色变量,从而获得必然的平滑过渡,而这在以前要么是不可能的,要么需要调用 JS
。
现在你可以:
- 为你的变量定义特定类型(数字、颜色、百分比
- 创建更安全、更可预测的代码
- 使用类型化值实现流畅动画
- 通过更好的浏览器优化来提高性能
这个特性在处理以下情况时非常有用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| :root { --gradient-stop: 50%; --theme-color: #ff0000; }
@property --gradient-stop { syntax: '<percentage>'; inherits: false; initial-value: 0%; }
@property --theme-color { syntax: '<color>'; inherits: true; initial-value: #ffffff; }
.gradient-background { background: linear-gradient( 90deg, blue var(--gradient-stop), red var(--gradient-stop) ); transition: --gradient-stop 0.3s ease; }
.gradient-background:hover { --gradient-stop: 75%; }
|
@starting-style
:为隐藏元素打造更好的动画
之前我们初始化动画 display:none
实现, 曾经是开发者永恒的痛点之一。现在我们可以使用 @starting-type
规则优雅地解决这个问题。
举例子:模态对话框,它从顶部进入屏幕。以前,为了获得流畅的动画,你必须在 JavaScript
或 CSS
中进行大量的复杂操作。元素要么突然出现,要么需要额外的包装元素和状态来进行过渡。
使用 @starting-style
,你可以设置元素加载并准备使用时的样式,以便从隐藏状态过渡平滑无缝。这使得 UI
更精细,但代码更少。浏览器负责处理动画的编程以及页面外观和行为方式的所有问题。
这个特性在构建适合残疾人士使用的应用程序界面方面尤其有用。这些过渡修复能够被屏幕阅读器和辅助技术理解,从而提高网站的可访问性,同时还能以视觉上更具吸引力的方式呈现它们。它提供以下功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| .modal { display: none; opacity: 1; transform: translateY(0); transition: transform 0.3s ease, opacity 0.3s ease; }
@starting-style { .modal { opacity: 0; transform: translateY(-20px); } }
.modal.show { display: block; }
.dropdown-menu { display: none; transform: scaleY(1); transition: transform 0.2s ease; }
@starting-style { .dropdown-menu { transform: scaleY(0); } }
.dropdown-menu.open { display: block; }
|
增强的数学函数:CSS
变得更强大
增加函数功能。
这些函数意味着在普通的 HTML
中,通常可以省略预处理器或 JavaScript
,尽管当然在许多情况下预处理器仍然有用。例如,使用原生数学函数可以更容易地管理诸如计算网格列宽度或设计响应式间距系统等任务。有了它,你就可以在 CSS
中进行复杂的数学运算。
round
类型(floor
、ceiling
、trunk
)的存在允许设计以前似乎不可能实现的改进布局精度。在任何情况下,当你处理网格系统或难以用预设的基于像素的宽度管理的内容时,这些函数都能提供你所需的控制,而无需离开你的样式表。新的数学函数证明了这一点:
- round(): 选择不同的入舍策略(向下取整、向上取整、截断)
- rem():余数运算
- mod():模运算, 类似于
JavaScript
上面这些函数为以下这些方面提供了新的特性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| .grid { --columns: 3; --gap: 20px;
display: grid; gap: var(--gap); grid-template-columns: repeat( var(--columns), calc(100% / var(--columns) - round(var(--gap) * (var(--columns) - 1) / var(--columns))) ); }
.list-item { padding: mod(var(--index), 2) * 1rem; }
.element { width: round(calc(100vw / 3));
height: round(down, calc(100vh / 4));
margin: round(up, calc(2.1rem)); }
|
使用 light-dark()
简化明/暗模式
管理明暗模式一直是一件比较麻烦的事情。新的 light-dark()
特性极大地简化了这个过程。
在真正的暗模式概念出现之前,只有两种创建它的方法,第一种是使用两种 CSS
样式,另一种是使用具有媒体查询的 CSS
变量。上述方法导致代码重复,从而导致代码重复和更高的维护成本。HTML5
的新 light-dark()
函数简化了同时设置这两者的过程。
此特性还增强了浏览器的性能,因为浏览器能够修改主题之间切换的性质。无需加载样式表或等待 JavaScript
更改那些变量,它根本不需要。它是无缝的并且快速发生,从而为用户提供比标准方法更好的体验。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| :root { --bg-color: white; --text-color: black; }
@media (prefers-color-scheme: dark) { :root { --bg-color: black; --text-color: white; } }
.element { background-color: light-dark(#ffffff, #121212); color: light-dark(#121212, #ffffff); border: 1px solid light-dark(#ddd, #333); box-shadow: 0 2px 4px light-dark(rgba(0,0,0,0.1), rgba(0,0,0,0.4)); }
.button { --button-bg: light-dark(#007bff, #0056b3); --button-text: light-dark(white, #e1e1e1);
background-color: var(--button-bg); color: var(--button-text); padding: 0.5rem 1rem; border-radius: 4px; }
|
使用用户伪类增强表单验证
!()[https://mmbiz.qpic.cn/sz_mmbiz_jpg/HLN2IKtpicicE6uqDgA0bpTyoibQvsjdeecvBrlmTGgTCDXMK0HNpknLyagPmN4icgXOj2FCM6wicCDLgg35Gvhxovw/640?wx_fmt=jpeg&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1]
借助 :user-valid
和 :user-invalid
伪类的引入,表单验证变得更加用户友好。
登录表单,你需要仅在用户尝试提交表单或离开输入字段时显示错误消息。以前,这只能通过使用 Javascript
事件监听器或复杂的 CSS hacks
来实现。新的伪类自然地实现了这一点,增强了页面的可用性,而无需额外的代码。
此特性还方便了访问;很容易。以前,表单验证状态对于某些屏幕阅读器来说难以识别,而现在它们更改表单的方式对每个人都更有用。显示错误消息的时间变得更有逻辑,表单未完成的实例减少了。这些新特性:
- 仅在用户交互后触发
- 防止过早显示错误消息
- 改善用户体验
- 降低代码复杂度
这比传统的 :valid
和 :invalid
伪类有了显著的改进,传统的伪类会立即触发,通常会导致糟糕的用户体验。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| .input-field { border: 2px solid #ccc; padding: 0.5rem; border-radius: 4px; }
.input-field:invalid { border-color: red; }
.input-field:user-invalid { border-color: red; animation: shake 0.3s ease-in-out; }
.input-field:user-valid { border-color: green; }
.error-message { display: none; color: red; font-size: 0.875rem; margin-top: 0.25rem; }
.input-field:user-invalid + .error-message { display: block; }
.success-icon { display: none; }
.input-field:user-valid ~ .success-icon { display: inline-block; }
@keyframes shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
|
interpolate-size
:为自动高度实现流畅动画
一个手风琴组件在展开时添加了内容。在此特性之前,动画高度的唯一方法是具有挑战性的,尤其是在处理动态内容时。主要问题在于开发者如何依赖 JavaScript 解决方案,或者使用固定高度动画,当内容较长时,这些动画就会停止工作。
因此,interpolate-size
属性可以轻松应对这些情况。浏览器会平滑地确定动画的正确路径,从而使过渡无缝,而不管内容的大小如何。即使你没有定义最终高度,它也能正常工作,这使得它更适合用于动态内容区域。现在你可以:
- 平滑地动画化 height: auto
- 创建流畅的下拉菜单动画
- 优雅地处理动态内容变化
- 实现更平滑的 UI 过渡
这个特性特别适用于:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| .accordion { overflow: hidden; }
.accordion-content { height: auto; padding: 1rem; background: #f5f5f5; interpolate-size: allow; transition: height 0.3s ease; }
.accordion-content.closed { height: 0; padding: 0 1rem; }
.dropdown { overflow: hidden; }
.dropdown-menu { height: auto; interpolate-size: allow; transition: height 0.3s ease; }
.dropdown-menu.collapsed { height: 0; }
.card { interpolate-size: allow; transition: all 0.3s ease; }
.card.expanded { height: auto; padding-bottom: 2rem; }
|