CSS 既简单又复杂。刚开始学起来很容易,但 CSS 不断更新,设计方法也在变化,总有新的功能和特性出现来解决旧问题。这可真是个让人又爱又恨的家伙!
最近几年,CSS 涌现出很多新特性,让网页设计变得更强大、更灵活。今天就来聊聊一些比较实用,并且已经得到广泛支持的新特性,帮助你提升网页设计的技能,做一个更牛的 web 设计师!
aspect-ratio: 轻松控制元素比例
aspect-ratio 属性可以方便地设置元素的宽高比例。它定义了元素宽度和高度的比例,根据已知的一边计算出另一边的尺寸。
这个属性非常实用,可以用于地图、卡片、视频、iframe 等等需要保持比例的元素,方便你实现自适应布局,让你的网页在各种屏幕上都看起来完美!
代码示例
创建一个元素,宽度占父元素的 100%,宽高比例为 2:3:
.item {
width: 100%;
aspect-ratio: 2 / 3;
}
对于图片和视频,可以将 aspect-ratio 属性和 object-fit 属性结合使用,aspect-ratio 定义元素的宽高比例,object-fit 则指定内容如何填充元素。
演示: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%
规范: W3C 编辑草案:https://w3c.github.io/csswg-drafts/css-sizing-4/#aspect-ratio
content-visibility: 提升网页加载速度
content-visibility 属性可以帮助网页更快地加载和渲染。通过这个属性,开发者可以告诉浏览器哪些部分包含独立的内容,这样,浏览器就可以优化页面渲染,延迟一些不必要的计算,从而提升网页加载速度。
代码示例
优化一个 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%
content-visibility 属性于 2020 年 8 月发布,目前支持 Chrome 和 Opera,但不支持 Safari 和 Firefox。
规范: https://www.w3.org/TR/CSS-contain-2/#content-visibility
Flexbox 中的 gap 属性
gap 属性用于设置 Flexbox 容器中子元素之间的间距。
使用一个值,表示行和列之间的间距相同。
使用两个值,分别表示行间距和列间距。
为了使代码更清晰,你也可以使用 row-gap 和 column-gap 属性分别设置行间距和列间距。
代码示例
为 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 年引入的,它从网格布局中迁移而来。但由于它简洁易用,很快便流行起来。
规范: https://w3c.github.io/csswg-drafts/css-align/#gap-shorthand
object-view-box:裁剪图片和视频
object-view-box 属性可以让你在网页上只显示图片或视频的特定区域,效果类似于 viewBox 属性。
object-view-box 在你想为不同的元素或不同的分辨率显示图片或视频的特定部分时,会非常有用。它还可以用于缩放或平移图片和视频。
代码示例
假设我们需要从图片中裁剪出一个正方形,上边距 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 属性的简写形式,它可以指定定位元素相对于其父元素的顶部、右侧、底部和左侧的内边距。
代码示例
创建一个完美定位的弹出模态窗口,占满浏览器窗口的整个区域:
.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%
规范: https://w3c.github.io/csswg-drafts/css-logical/#propdef-inset
scrollbar-gutter: 预留滚动条空间
scrollbar-gutter 属性可以帮助你预留滚动条的空间,即使滚动条出现也不会导致内容重新排版。
scrollbar-gutter 属性对于充满动态内容的单页面应用的开发者来说非常有用。之前,如果这种应用中出现了滚动条,所有内容都会沿着滚动条的宽度向左移动。
代码示例
这段代码可以为滚动条预留空间,确保滚动条出现时内容不会发生位移。
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 属性则用于截断多行文本。
代码示例
使用 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%
这个属性使用以下前缀: -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 属性,它会根据字体的大小改变字体的外观。
代码示例
加载可变字体的代码:
@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 年底首次推出,并且拥有良好的浏览器支持。
CSS 自定义属性 (变量)
CSS 变量就像 CSS 中的变量,你可以定义一些值,然后在代码中重复使用,就像给颜色、尺寸、字体等等定义一个别名。 这样,以后想要修改这些值,只需要修改变量,而不用改动所有使用该值的代码,方便又高效!
CSS 变量还可以通过 JavaScript 来控制,实现动态效果。
获取 CSS 变量的值:
element.style.getPropertyValue('--main-color');
设置 CSS 变量的值:
element.style.setProperty('--translate', `${currentScroll}px`);
用 CSS 变量实现深色和浅色主题之间的过渡,简直不要太方便!
代码示例
声明一个变量:
: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 变量。
规范: https://www.w3.org/TR/CSS-variables/
min(), max(), clamp() CSS 函数
min(), max(), 和 clamp() CSS 函数都是比较函数。它们接收多个值,并返回其中一个值。min() 函数返回最小值,max() 函数返回最大值。clamp() 函数接收三个值:最小值、推荐值和最大值,如果推荐值在指定范围内,则返回推荐值。
这些比较函数可以扩展我们创建动态布局和设计灵活组件的能力。你可以使用它们来调整元素大小、字体、缩进等等。尽管我们之前已经可以为元素的宽度和高度指定最小值和最大值,但正是比较函数让对字体大小和缩进进行同样操作成为可能。
代码示例和以前的做法
有一个常见的任务——创建一个容器元素,使其跨越父元素的整个宽度,但限制其最大尺寸。传统的解决方案如下:
.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 年引入的,它们在所有主流浏览器中都有效。
规范: 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了!
我是前端宝哥,每日分享前端开发技术,关注下面二维码,围观我的朋友圈。
备注【文章群】可以进文章分享群,
备注【技术群】可以进技术交流群,
备注【副业群】可以进程序员副业群。
关注下方公众号加星标,送我的电子书资料
回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF
回复「Vue脑图」获取 Vue 相关脑图
回复「思维图」获取 JavaScript 相关思维图
回复「简历」获取简历制作建议
回复「简历模板」获取精选的简历模板
回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。
回复「知识点」下载高清JavaScript知识点图谱
回复「读书」下载成长的相关电子书
觉得好看,请关注我,点“在看”