CSS

前言

随着前端的不断发展,更多新的 CSS 属性不断加入提案,本文列举 7 个不常用但很有用且见过也可能没见过的 CSS 属性,带大家领略 CSS 之美。

1、position: sticky

DM_20221128142509_001.JPG
不知道大家平时业务开发中有没有碰到像上图一样的吸顶的需求:标题在滚动的时候,会一直贴着最顶上。
这种场景实际上很多:比如表格的标题栏、网站的导航栏、手机通讯录的人名首字母标题等等。如果让大家自己动手做的话,是不是会用 js 结合 css 来实现呢?以前确实是这样的,直到后来 position 属性新增了一个属性值 sticky ,前端程序员才迎来了小春天。

  1. // css 部分
  2. .container {
  3. background-color: oldlace;
  4. height: 200px;
  5. width: 140px;
  6. overflow: auto;
  7. }
  8. .container div {
  9. height: 20px;
  10. background-color: aqua;
  11. border: 1px solid;
  12. }
  13. .container .header {
  14. position: sticky;
  15. top: 0;
  16. background-color: rgb(187, 153, 153);
  17. }
  18. // html 部分
  19. <div class="container">
  20. <div class="header">Header</div>
  21. <div>1</div>
  22. <div>2</div>
  23. <div>3</div>
  24. </div>

就这么简单?对,就这么简单,但是小伙伴们使用的时候要注意兼容性。

2、:empty 选择器

DM_20221128142721_001.jpg
平时开发的时候数据都是通过请求接口获取的,也会存在接口没有数据的情况。这个时候正常的做法是给用户一个提示,让用户知道当前不是出 bug 了,而是确实没有数据。
一般的做法是人为的判断当前数据返回列表的长度是否为 0,如果为 0 则显示一个 “暂无数据” 给用户,反之则隐藏该提示。写过 Vue 的小伙伴是不是经常这么做:

  1. <div>
  2. <template v-if="datas.length">
  3. <div v-for="data in datas"></div>
  4. </template>
  5. <template v-else>
  6. <div>暂无数据</div>
  7. </template>
  8. </div>

但是有了 :empty 这个选择器后,大可以把这个活交给 CSS 来干。

  1. .container {
  2. height: 400px;
  3. width: 600px;
  4. background-color: antiquewhite;
  5. display: flex;
  6. justify-content: center;
  7. align-items: center;
  8. }
  9. .container:empty::after {
  10. content: "暂无数据";
  11. }

通过 :empty 选中内容为空的容器,然后通过伪元素为空容器添加提示。是不是方便很多呢?

3、gap

小伙伴们日常开发中,都有用过 padding 和 margin 吧,margin 一般用做边距,让两个元素隔开一点距离,但是对于一些场景下,很难通过计算得到一个除的尽的值,比如 100px 要让 3 个元素等分,且每个元素隔开 10px,这就很尴尬了。
没关系!可以用 gap 属性,gap 属性它适用于 Grid 布局、Flex 布局以及多列布局,并不一定只是 Grid 布局中可以使用。
比如要让每个元素之间隔开 20px, 那么使用 gap 可以这样:

  1. display: flex | grid
  2. gap: 20px;

是不是很简单呢?

4、background-clip: text

这个属性可能小伙伴们用的不多,有什么用呢?简单来说就是可以做一个带背景的文字效果:
2022-11-28-14-19-48.075798900.png
DM_20221128142509_002.JPGDM_20221128142509_003.JPG
图 1 + 图 2 = 图 3。是不是很惊艳呢?大家平时 background-clip 是不是都用来做一些裁切效果?in知道它还有个属性值是 text 吗?background-clip: text 用来做带背景的文字效果,相信大家平时浏览一些网站的时候都会看到类似的实现,实际上通过 CSS 也能做到这种效果,可不要傻傻的以为都是用制图工具做的。

5、user-select

很多人不知道这个属性是什么意思。大家看看下图:
惊艳的 CSS 属性 - 图6
网页和 APP 有个不同点是,网页上的字是可以通过光标选中的,而 APP 的不行。
有的小伙伴可能会疑惑:那网页上也用不着这个属性?
非也非也,现在很多新的技术产生,可以在 APP 上嵌套 webview 或者是网页,比如 Electron 做的 桌面端应用 ,大家没见过哪个桌面端应用是可以光标选中的吧?
而 user-select 属性可以 禁用光标选中 ,让网页看着和移动端一样。

6、:invalid 伪类

**:invalid** 表示任意内容未通过验证的 input 或其他 form 元素。什么意思呢?举个例子。
这是一个表单。

  1. <form>
  2. <label for="url_input">Enter a URL:</label>
  3. <input type="url" id="url_input" />
  4. <br />
  5. <br />
  6. <label for="email_input">Enter an email address:</label>
  7. <input type="email" id="email_input" required/>
  8. </form>

需求是让 input 当值有效时,元素颜色为绿色,无效时为红色。

  1. input:invalid {
  2. background-color: #ffdddd;
  3. }
  4. form:invalid {
  5. border: 5px solid #ffdddd;
  6. }
  7. input:valid {
  8. background-color: #ddffdd;
  9. }
  10. form:valid {
  11. border: 5px solid #ddffdd;
  12. }
  13. input:required {
  14. border-color: #800000;
  15. border-width: 3px;
  16. }
  17. input:required:invalid {
  18. border-color: #C00000;
  19. }

有了 :invalid 属性后,就可以不用 JS 也能实现校验提示的效果了。

7、:focus-within 伪类

**:focus-within** 表示一个元素获得焦点,或该元素的后代元素获得焦点,就会匹配上。啥意思呢?
话不多说,先看图:
惊艳的 CSS 属性 - 图7

  1. // CSS
  2. form {
  3. border: 1px solid;
  4. width: 400px;
  5. height: 300px;
  6. display: flex;
  7. justify-content: center;
  8. align-items: center;
  9. }
  10. form:focus-within {
  11. box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.3);
  12. background-color: beige;
  13. }
  14. // HTML
  15. <form>
  16. <input type="text" id="ipt" placeholder="请输入..." />
  17. </form>

可以根据子元素的状态来改变父元素的样式,方便的很。也能玩出不少花样来。
有的小伙伴看完后可能会想:嗷,也没啥的啊,这有啥花样?

8、mix-blend-mode:difference

mix-blend-mode:difference 属性描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合。其中,difference 表示差值。
2022-11-28-14-19-52.121420500.png
如果给你这张图,会怎么去绘制?是不是很麻烦。
但是如果用 mix-blend-mode:difference 这个属性,就可以很容易的实现。

  1. .mode {
  2. display: flex;
  3. justify-content: center;
  4. align-items: center;
  5. mix-blend-mode:difference;
  6. }
  7. .dark {
  8. position: relative;
  9. left: 6px;
  10. height: 24px;
  11. width: 24px;
  12. background-color: grey;
  13. border-radius: 50%;
  14. }
  15. .light {
  16. mix-blend-mode:difference;
  17. position: relative;
  18. left: -6px;
  19. height: 16px;
  20. width: 16px;
  21. border-radius: 50%;
  22. border: 4px solid grey;
  23. }