2024 年 10 个很实用的 CSS 新特性,你不一定知道!

CSS 既简单又复杂。刚开始学起来很容易,但 CSS 不断更新,设计方法也在变化,总有新的功能和特性出现来解决旧问题。这可真是个让人又爱又恨的家伙!

最近几年,CSS 涌现出很多新特性,让网页设计变得更强大、更灵活。今天就来聊聊一些比较实用,并且已经得到广泛支持的新特性,帮助你提升网页设计的技能,做一个更牛的 web 设计师!

aspect-ratio: 轻松控制元素比例

aspect-ratio 属性可以方便地设置元素的宽高比例。它定义了元素宽度和高度的比例,根据已知的一边计算出另一边的尺寸。

这个属性非常实用,可以用于地图、卡片、视频、iframe 等等需要保持比例的元素,方便你实现自适应布局,让你的网页在各种屏幕上都看起来完美!

85af5234dc6493502c96f4276a819049.png
image.png

代码示例

创建一个元素,宽度占父元素的 100%,宽高比例为 2:3:

.item {
  width: 100%;
  aspect-ratio: 2 / 3;
}

对于图片和视频,可以将 aspect-ratio 属性和 object-fit 属性结合使用,aspect-ratio 定义元素的宽高比例,object-fit 则指定内容如何填充元素。

5b98d1b5544c9edb5ff2ea5435ff23f6.png
image.png

演示:https://codepen.io/irinainina/pen/JjvwaQq

以前都是怎么做的?

在 aspect-ratio 出现之前,我们通常使用 padding-top 属性来保持比例,因为百分比的 padding 值是基于父元素的宽度。

例如,为了设置 16:9 视频的宽高比例,我们必须编写以下代码:

.video {
  width: 100%;
  padding-top: 56.25%;
}

这种写法比较麻烦,而且不太直观,更像是一个技巧而不是一个基本语言特性。

现在,我们可以使用 aspect-ratio 属性来定义比例:

.video {
  width: 100%;
  aspect-ratio: 16 / 9;
}

是不是简洁明了多了?

浏览器支持:  91.23%

ade6335d8e1de3f4e8fc8ab8fc7a5547.png
image.png

规范:  W3C 编辑草案:https://w3c.github.io/csswg-drafts/css-sizing-4/#aspect-ratio

content-visibility: 提升网页加载速度

content-visibility 属性可以帮助网页更快地加载和渲染。通过这个属性,开发者可以告诉浏览器哪些部分包含独立的内容,这样,浏览器就可以优化页面渲染,延迟一些不必要的计算,从而提升网页加载速度。

2f5e6570711956515b1bffe4b075b49c.png
image.png

代码示例

优化一个 section 的加载速度:

.section {
  content-visibility: auto;
  contain-intrinsic-size: 1000px;
}

使用 content-visibility 属性,浏览器只会加载和渲染当前用户在屏幕上看到的区域。对于其他部分,只需要指定其高度,contain-intrinsic-size 充当占位符。

演示:https://codepen.io/irinainina/pen/wvjZLor

以前都是怎么做的?

在 content-visibility 出现之前,浏览器会加载和渲染页面上的所有部分,无论它们是否在用户视野范围内。而 content-visibility 则可以帮助浏览器只加载和渲染用户当前可见的区域,显著提升渲染速度。

浏览器支持:  72.95%

2fd9613c672236be7f8e8a05e7240620.png
image.png

content-visibility 属性于 2020 年 8 月发布,目前支持 Chrome 和 Opera,但不支持 Safari 和 Firefox。

规范:  https://www.w3.org/TR/CSS-contain-2/%23content-visibility

Flexbox 中的 gap 属性

gap 属性用于设置 Flexbox 容器中子元素之间的间距。

  • 使用一个值,表示行和列之间的间距相同。

  • 使用两个值,分别表示行间距和列间距。

为了使代码更清晰,你也可以使用 row-gap 和 column-gap 属性分别设置行间距和列间距。

615daddf0f7525111d0d667b05d853dd.png
image.png

代码示例

为 Flex 容器设置 gap 属性。使用 row-gap 和 column-gap 属性分别设置 Flex 元素的行间距和列间距:

.item-container {
  display: flex;
  row-gap: 30px;
  column-gap: 20px;
}

同样的代码还可以写得更简洁:

.item-container {
  display: flex;
  gap: 30px 20px;
}

演示:https://codepen.io/irinainina/pen/QWrzJaL

以前都是怎么做的?

在 gap 属性出现之前,我们通常使用 margin 属性来设置 Flex 元素之间的间距。 但 margin 属性会导致元素与容器边缘之间也产生间距。

为了解决这个问题,可以使用各种方法:

  • 使用 :last-child 伪类,可以指定最后一个元素没有缩进;

  • 设置 margin 属性的负值;

  • 使用三字符 CSS 选择器,俗称“开膛破肚的猫头鹰选择器”。它看起来像 * + *,像猫头鹰空洞的眼神一样,因此得名。这种选择器可以让你只为在相同类型元素之后出现的元素指定属性。

除了复杂性和难以理解之外,这些方法还有一个缺点——它们只适用于 Flex 元素排列成一行的情况,不适合多行结构。

而 gap 属性适用于单行和多行排列的 Flex 元素,可以方便地设置元素之间的间距,而无需使用这些复杂的技术。

浏览器支持:  95.42%

gap 属性是在 2021 年引入的,它从网格布局中迁移而来。但由于它简洁易用,很快便流行起来。

11c484495bf3736ec4153fb894be2ecf.png
image.png

规范:  https://w3c.github.io/csswg-drafts/css-align/#gap-shorthand

object-view-box:裁剪图片和视频

object-view-box 属性可以让你在网页上只显示图片或视频的特定区域,效果类似于 viewBox 属性。

object-view-box 在你想为不同的元素或不同的分辨率显示图片或视频的特定部分时,会非常有用。它还可以用于缩放或平移图片和视频。

45c7ac444e7277bc51049cd289ce5bab.png
image.png

代码示例

假设我们需要从图片中裁剪出一个正方形,上边距 25%,右边距 20%,下边距 15%,左边距 5%。实现这一功能的代码如下:

.img {
  aspect-ratio: 1;
  width: 300px;
  object-view-box: inset(25% 20% 15% 5%);
  object-fit: cover;
}

inset(25% 20% 20% 15% 5%) 的值表示要显示的图片原始区域中的上、右、下、左位置。而 object-fit 属性设置为 cover 可以确保结果片段不会变形。

目前,我们还无法通过 transition 属性来动画化 object-view-box 属性,但可以使用 @keyframes 动画来实现平滑的缩放或视窗变化。

演示:https://codepen.io/irinainina/pen/JjvzGOv

以前都是怎么做的?

在 object-view-box 属性出现之前,如果要裁剪图片或视频,我们需要使用一个带有 overflow: hidden; 属性的包装元素,并在其中定位和缩放内容。对于图片,你也可以使用 background-image 属性而不是 img 标签,并使用 background-position 和 background-size 属性进行定位和缩放。另一种常见的解决方法(可能不太理想)是使用不同的文件来存放同一图片的不同片段。

浏览器支持:

object-view-box 属性是 2022 年 5 月才新推出的,但最新版本的 Google Chrome 和 Opera 已经支持。

规范:  https://drafts.csswg.org/CSS-images-4/#the-object-view-box

inset:简化定位

inset 属性可以替代 top, right, bottom, left 这四个属性,一次性指定定位元素的四个方向的内边距。

inset 就像 margin 和 padding 属性的简写形式,它可以指定定位元素相对于其父元素的顶部、右侧、底部和左侧的内边距。

21b7499dbce15755b1de67d7b8ba4205.png
image.png

代码示例

创建一个完美定位的弹出模态窗口,占满浏览器窗口的整个区域:

.modal {
  position: absolute;
  inset: 0;
}

短短一行代码就可以实现将一个绝对定位的元素拉伸至全屏,是不是很方便?

演示:https://codepen.io/irinainina/pen/OJZqwOZ

以前都是怎么做的?

在 inset 属性出现之前,我们需要这样写代码来实现将定位元素拉伸至全屏:

.modal {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

使用一个属性代替四个属性,是不是更加简洁方便呢?

浏览器支持:  92.12%

e42d7c64f42292fa45a1b7ba148fbdac.png
image.png

规范:  https://w3c.github.io/csswg-drafts/css-logical/#propdef-inset

scrollbar-gutter: 预留滚动条空间

scrollbar-gutter 属性可以帮助你预留滚动条的空间,即使滚动条出现也不会导致内容重新排版。

scrollbar-gutter 属性对于充满动态内容的单页面应用的开发者来说非常有用。之前,如果这种应用中出现了滚动条,所有内容都会沿着滚动条的宽度向左移动。

12d0ca5933a982b4d97e8856c22180d8.png
image.png
295a8a0f5f7ae28680281f658f6daf3f.png
image.png

代码示例

这段代码可以为滚动条预留空间,确保滚动条出现时内容不会发生位移。

html {
  scrollbar-gutter: stable both-edges;
}

演示:https://codepen.io/irinainina/pen/PoeLMLY

以前都是怎么做的?

在 scrollbar-gutter 属性出现之前,为了防止滚动条出现时内容发生位移,我们需要使用 margin 负值和 overflow-x: hidden 属性来对 HTML 进行 hack:

html {
  overflow-x: hidden;
  margin-right: calc(-1 * (100vw - 100%));
}

浏览器支持:  74.6%

这个属性得到了所有主流浏览器的支持。

规范:  https://w3c.github.io/csswg-drafts/css-overflow/#scrollbar-gutter-property

text-overflow 和 line-clamp:截断文本

text-overflow 和 line-clamp 属性用于在文本超出视窗时截断文本。 text-overflow 属性用于截断单行文本,line-clamp 属性则用于截断多行文本。

64135dd6f5975f1e509fc9c194963d79.png
image.png

代码示例

使用 text-overflow 属性,将一行文本截断为容器的宽度,并在末尾添加三个点:

.title {
  display: block;
  width: 350px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

text-overflow 属性只对块级容器有效,前提是元素还具有 white-space 属性设置为 nowrap,以及 overflow 属性设置为 hidden、scroll 或 auto。

text-overflow 属性的可用值为 clip (文本在父块的边缘被精确裁剪)和 ellipsis (在行末添加省略号)。

line-clamp 属性需要使用 -webkit 前缀。值为 2 表示只显示两行文本。

.text {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

line-clamp 属性只对块级容器有效,需要与 display 和 -webkit-box-orient 属性一起使用。还需要 overflow 属性设置为 hidden,以便在指定行数之后截断内容。

演示:https://codepen.io/irinainina/pen/dyerJgQ

以前都是怎么做的?

使用 JavaScript 可以轻松地将文本截断为指定字符数:

const cutText = (text, count) => {
  return text.slice(0, count) + '...';
};

count 表示要截断的字符数。 这种方法虽然简单,但有一个缺点:不像 CSS,JavaScript 无法识别文本的行数。它只能根据字符数进行截断,但包含相同字符数的文本可能占用不同的行数。因此,与 CSS 相比,使用 JavaScript 截断文本的可靠性较低。

浏览器支持:  96,24%

7984b3611500bf04faa13f400e37b6c4.png
image.png

这个属性使用以下前缀: -webkit-line-clamp

规范:  https://w3c.github.io/csswg-drafts/css-overflow-3/#propdef--webkit-line-clamp

可变字体 (Variable Fonts)

可变字体提供了一个独特的特性:一个字体文件可以包含所有风格。 对于常规字体,如果你在布局中使用两种风格,例如 regular 和 bold,则需要上传两个字体文件。 而对于可变字体,只需要加载一个包含所有字体变体的文件,是不是更方便了?

可变字体与常规字体一样使用,但实际上,它们可以提供更多功能。对于常规字体,font-weight 属性的值从 100 到 900,以 100 为增量,而对于可变字体,它可以是 1 到 999 之间的任何整数。对于普通字体,font-style 属性取两个值 normal 和 italic,而对于可变字体,你可以指定从 -90deg 到 90deg 的倾斜角。可变字体的 font-stretch 属性从 50% (窄字体)到 200% (宽字体)变化,其中正常比例对应于 100%。然后是 font-optical-sizing 属性,它会根据字体的大小改变字体的外观。

d362ed2b06b697960ff2088fd48219c3.png
image.png

代码示例

加载可变字体的代码:

@font-face {
  font-family: Inter;
  src: url("assets/fonts/Inter.woff2");
}

Inter 就是一个可变字体,只需要加载一个字体文件,就能包含所有字体风格。

以前都是怎么做的?

加载静态字体的代码:

@font-face {
  font-family: Roboto;
  src: url("assets/fonts/RobotoThin.woff2");
  font-weight: 100;
}
@font-face {
  font-family: Roboto;
  src: url("assets/fonts/RobotoRegular.woff2");
  font-weight: 400;
}

Roboto 是一个静态字体,每个字体风格都需要单独加载一个字体文件。

浏览器支持:  95,95%

可变字体在 2016 年底首次推出,并且拥有良好的浏览器支持。

61b0f9dd1a09e3d54e51536adee2e1e7.png
image.png

CSS 自定义属性 (变量)

CSS 变量就像 CSS 中的变量,你可以定义一些值,然后在代码中重复使用,就像给颜色、尺寸、字体等等定义一个别名。 这样,以后想要修改这些值,只需要修改变量,而不用改动所有使用该值的代码,方便又高效!

CSS 变量还可以通过 JavaScript 来控制,实现动态效果。

获取 CSS 变量的值:

element.style.getPropertyValue('--main-color');

设置 CSS 变量的值:

element.style.setProperty('--translate', `${currentScroll}px`);

用 CSS 变量实现深色和浅色主题之间的过渡,简直不要太方便!

2b8a435bbcdad1ead2ab3c034efeeb16.png
image.png

代码示例

声明一个变量:

:root {
  --color-red: #79142B;
}

如何获取 CSS 变量的值:

.item {
  color: var(--color-red);
}

演示:https://codepen.io/irinainina/pen/bGMyjva

以前都是怎么做的?

CSS 变量最初出现在 CSS 框架中,后来被添加到正规的 CSS 中,这无疑是一个巨大的进步,因为它可以让代码更优化,更易读,更灵活。

浏览器支持:  96,7%

CSS 变量在 2017 年被提出,目前处于 W3C 的候选推荐 (CR) 阶段,也就是说,在本文中描述的其他特性中,它是最接近实际实现的。所有主流浏览器都支持 CSS 变量。

a909b2f7bfc41c9241884cf404925cf5.png
image.png

规范:  https://www.w3.org/TR/CSS-variables/

min(), max(), clamp() CSS 函数

min(), max(), 和 clamp() CSS 函数都是比较函数。它们接收多个值,并返回其中一个值。min() 函数返回最小值,max() 函数返回最大值。clamp() 函数接收三个值:最小值、推荐值和最大值,如果推荐值在指定范围内,则返回推荐值。

这些比较函数可以扩展我们创建动态布局和设计灵活组件的能力。你可以使用它们来调整元素大小、字体、缩进等等。尽管我们之前已经可以为元素的宽度和高度指定最小值和最大值,但正是比较函数让对字体大小和缩进进行同样操作成为可能。

6a2420ef8e1672d15fbd2e99f6c3aa2d.png
image.png

代码示例和以前的做法

有一个常见的任务——创建一个容器元素,使其跨越父元素的整个宽度,但限制其最大尺寸。传统的解决方案如下:

.container {
  width: 100%;
  max-width: 1024px;
}

使用 min() 函数,我们可以用一行代码实现相同的效果:

.container {
  width: min(100%, 1024px);
}

另一个常见的挑战是创建一个高度为 100vh 的 section,同时指定其最小高度:

.section {
  height: 100vh;
  min-height: 680px;
}

使用 max() 函数,我们可以用一行代码实现相同的效果:

.section {
  height: max(100vh, 680px);
}

需要注意的是,min() 和 max() 函数的参数顺序无关紧要。无论如何,前者返回较小的值,后者返回较大的值。但 clamp() 函数的参数顺序必须从小到大:

.design {
  width: clamp(350px, 50%, 650px);
}

我们有一个设计元素,占据父元素宽度的一半,但它的宽度不能小于 350 像素,也不能大于 650 像素。

在 clamp() 函数出现之前,我们通常使用媒体查询来解决这个问题,为不同的屏幕分辨率指定不同的元素宽度。使用 clamp() 函数,这个任务变得更加简单,元素尺寸的变化在指定的取值范围内是连续的。

演示:https://codepen.io/irinainina/pen/bGMyRaa

浏览器支持:  94,44%

比较函数是在 2020 年引入的,它们在所有主流浏览器中都有效。

7f2cac529bf2a89bdaa99f900034a3c9.png
image.png

规范:  https://drafts.csswg.org/CSS-values-4/#comp-func

总结

CSS 可以说是最简单但也最复杂的语言之一。刚开始学起来很容易,但 CSS 不断更新,设计方法也在变化,不断推出新的功能和特性来解决旧问题。 这要求开发者始终关注最新变化,不断学习和提升。

希望这篇文章介绍的 CSS 特性和功能对你有所帮助,并能应用到你的工作中!


最后,如果你觉得宝哥的分享还算实在,就给我点个赞,关注一波。分享出去,也许你的转发能给别人带来一点启发。

往期推荐

38个Vue、Nuxt 和 Vite 技巧、窍门和实践的合集

12 种 Vue 设计模式

CSS 秘密武器:25 个小技巧,助你写出更优雅的代码!

JavaScript 的新技能:5 大技巧,打造更强大的 Web 应用

Vue 3 表单大揭秘: 用 ref、组合式 API 和 v-for 打造你的专属表单!

程序员必备:9 个超赞的速查表网站,2024 年开发效率翻倍!

Vue 如何处理异步组件加载错误

Vue 3 将推出新特性,可以抛弃虚拟DOM了!

我是前端宝哥,每日分享前端开发技术,关注下面二维码,围观我的朋友圈。

319c5a81bf135bacac8f3843bb208824.png

备注【文章群】可以进文章分享群,

备注【技术群】可以进技术交流群,

备注【副业群】可以进程序员副业群。

关注下方公众号加星标,送我的电子书资料

  • 回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF

  • 回复「Vue脑图」获取 Vue 相关脑图

  • 回复「思维图」获取 JavaScript 相关思维图

  • 回复「简历」获取简历制作建议

  • 回复「简历模板」获取精选的简历模板

  • 回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。

  • 回复「知识点」下载高清JavaScript知识点图谱

  • 回复「读书」下载成长的相关电子书

236c3291dcb38a81935b4fb742c11f5d.png

觉得好看,请关注我,点“在看”937f7a176f85928daa6aa9b64f3ee3fb.gif

  • 22
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值