• 那些惊艳一时的 CSS 属性


    1.position: sticky

    在这里插入图片描述

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

    // css 部分
    .container {
        background-color: oldlace;
        height: 200px;
        width: 140px;
        overflow: auto;
      }
      .container div {
        height: 20px;
        background-color: aqua;
        border: 1px solid;
      }
      .container .header {
        position: sticky;
        top: 0;
        background-color: rgb(187, 153, 153);
    }
    
    // html 部分
    <div class="container">
      <div class="header">Header</div>
      <div>1</div>
      <div>2</div>
      <div>3</div>
    </div>
    
    • 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

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

    2. :empty 选择器

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

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

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

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

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

    3. gap

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

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

    4. background-clip: text

    这个属性可能小伙伴们用的不多,有什么用呢?简单来说就是可以做一个带背景的文字效果:
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    图 1 + 图 2 = 图 3。是不是很惊艳呢?大家平时 background-clip 是不是都用来做一些裁切效果?in知道它还有个属性值是 text 吗?background-clip: text 用来做带背景的文字效果,相信大家平时浏览一些网站的时候都会看到类似的实现,实际上通过 CSS 我们也能做到这种效果,可不要傻傻的以为都是用制图工具做的。

    <p>Lorem ......</p>
    
    p {
      color: transparent;
      background: url(https://media.giphy.com/media/Ju7l5y9osyymQ/giphy.gif) center/cover;
      background-clip: text;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5. user-select

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

    6. :invalid 伪类

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

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

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

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

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

    7. :focus-within 伪类

    :focus-within 表示一个元素获得焦点,或该元素的后代元素获得焦点,就会匹配上。啥意思呢?
    话不多说,先看图:
    在这里插入图片描述

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

    8. mix-blend-mode:difference

    mix-blend-mode: difference,意为差值模式
    该混合模式会查看每个通道中的颜色信息,比较底色和绘图色,用较亮的像素点的像素值减去较暗的像素点的像素值。

    与白色混合将使底色反相;与黑色混合则不产生变化。
    通俗一点就是上方图层的亮区将下方图层的颜色进行反相,暗区则将颜色正常显示出来,效果与原图像是完全相反的颜色。

    例子1
    在这里插入图片描述

    //css
    .mode {
        display: flex;
        justify-content: center;
        align-items: center;
        mix-blend-mode:difference;
    }
      .dark {
        position: relative;
        left: 6px;
        height: 24px;
        width: 24px;
        background-color: grey;
        border-radius: 50%;
    }
    .light {
        mix-blend-mode:difference;
        position: relative;
        left: -6px;
        height: 16px;
        width: 16px;
        border-radius: 50%;
        border: 4px solid grey;
    }
    //html
    <div class="mode">
    	<div class="dark"></div>
    	<div class="light"></div>
    </div>
    
    • 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

    例子2
    在这里插入图片描述

    <div class="main"></div>
    
    .main{
        width: 100%;
        height: 100%;
        background: linear-gradient(45deg, #000 0, #000 50%, #fff 50%);
        position: relative;
        
        &::before{
            content:'LOADING';
            position: absolute;
            font-size: 50px;
            width: 100%;
            height: 100%;
            top: 40%;
            left: 20%;
            color: #fff;
            mix-blend-mode: difference;
            animation: move 3s infinite linear alternate;
        }
    } 
    @keyframes move {
        0% {
            transform: translateX(20%);
        }
        100% {
            transform: translateX(-20%);
        }
    
    • 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

    9.counter

    css也可以像js进行计算,当我们需要设置序号或者想知道某种情况出现的次数时,我们可以用一下属性

    //counter-increment: record; 		/* 为计数器每次自增 1(默认) */
    //counter-increment: record 2; 	/* 为计数器每次自增 2 */
    //html
    <body>
    	<h3>lalala</h3>
      	<h3>lalala</h3>
      	<h3>lalala</h3>
    </body>
    
    //css
    body{
    	counter-reset: first;	/* 创建一个计数器first*/
    }
    h3:before {
      	content: counter(first)": " ;
    }
    h3 {
      	counter-increment: first 2;		/* 为计数器first每次增加2 */
    }
    //会得到结果
    //2:lala
    //4:lala
    //6:lala
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    10.clip-path

    该属性用于截取元素的部分用于显示

    polygon

    • 值为多个坐标点组成,坐标第一个值是x方向,第二个值是y方向。
    • 左上角为原点,右下角是(100%,100%)的点。
    //css
    body {
      background-color: #000;
    }
     
    .fa {
      border: 1px solid #fff;
      color: yellowgreen;
      padding: 10px;
      margin: 10px;
    }
     
    .fa>div {
      width: 110px;
      height: 110px;
      background-color: yellowgreen;
      margin: 20px auto;
    }
     
    .polygon1 {
      clip-path: polygon(50% 0px, 100% 100%, 0px 100%)
    }
     
    .polygon2 {
      clip-path: polygon(0px 50%, 50% 0, 100% 50%, 50% 100%)
    }
     
    .polygon3 {
      clip-path: polygon(0% 60%, 20% 0%, 60% 0%, 40% 60%)
    }
    
    //html
    <div class="fa">
      <p>polygon</p>
      <p>值为多个坐标点组成,坐标第一个值是x方向,第二个值是y方向。</p>
      <p>左上角为原点,右下角是(100%,100%)的点。</p>
      <div class="polygon1"></div>
      <div class="polygon2"></div>
      <div class="polygon3"></div>
    </div>
    
    • 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

    在这里插入图片描述
    circle

    • 值为一个坐标点和半径组成。
    • 左上角为原点,右下角是(100%,100%)的点。
    • 定义半径的时候可以用at关键字来定义坐标。
    //css
    body {
      background-color: #000;
    }
     
    .fa {
      border: 1px solid #fff;
      color: yellowgreen;
      padding: 10px;
      margin: 10px;
    }
     
    .fa>div {
      width: 110px;
      height: 110px;
      background-color: yellowgreen;
      margin: 20px auto;
    }
     
    .circle1 {
      clip-path: circle(50% at 50% 50%)
    }
     
    .circle2 {
      clip-path: circle(70% at 50% 50%)
    }
     
    .circle3 {
      clip-path: circle(30% at 10% 10%)
    }
    
    //html
    <div class="fa">
      <p>circle</p>
      <p>值为一个坐标点和半径组成。</p>
      <p>左上角为原点,右下角是(100%,100%)的点。</p>
      <p>定义半径的时候可以用at关键字来定义坐标。</p>
      <div class="circle1"></div>
      <div class="circle2"></div>
      <div class="circle3"></div>
    </div>
    
    • 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

    在这里插入图片描述
    ellipse

    • 值为椭圆的x轴半径,y轴半径,定位椭圆的坐标三部分组成。
    • 左上角为原点,右下角是(100%,100%)的点。
    • at关键字将半径和坐标分开。
    //css
    body {
      background-color: #000;
    }
     
    .fa {
      border: 1px solid #fff;
      color: yellowgreen;
      padding: 10px;
      margin: 10px;
    }
     
    .fa>div {
      width: 110px;
      height: 110px;
      background-color: yellowgreen;
      margin: 20px auto;
    }
     
    .ellipse1 {
      clip-path: ellipse(30% 20% at 50% 50%)
    }
     
    .ellipse2 {
      clip-path: ellipse(20% 30% at 50% 50%)
    }
     
    .ellipse3 {
      clip-path: ellipse(60% 10% at 10% 10%)
    }
    //html
    <div class="fa">
      <p>ellipse</p>
      <p>值为椭圆的x轴半径,y轴半径,定位椭圆的坐标三部分组成。</p>
      <p>左上角为原点,右下角是(100%,100%)的点。</p>
      <p>at关键字将半径和坐标分开</p>
      <div class="ellipse1"></div>
      <div class="ellipse2"></div>
      <div class="ellipse3"></div>
    </div>
    
    • 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

    在这里插入图片描述
    inset

    • 值为(上 右 下 左 round 左上角radius 右上角radius 右下角radius 左下角radius)
    • round前面的数值,表示的是距离,如果第一个值为25%,则表示图像在上面从25%开始绘制。
    //css
    body {
      background-color: #000;
    }
     
    .fa {
      border: 1px solid #fff;
      color: yellowgreen;
      padding: 10px;
      margin: 10px;
    }
     
    .fa>div {
      width: 110px;
      height: 110px;
      background-color: yellowgreen;
      margin: 20px auto;
    }
     
    .inset1 {
      clip-path: inset(25% 0% 25% 0% round 0% 25% 0% 25%)
    }
     
    .inset2 {
      clip-path: inset(0% 25% 25% 0% round 25% 25% 25% 0%)
    }
     
    .inset3 {
      clip-path: inset(25% 25% 0% 0% round 0% 25% 0% 25%)
    }
    //html
    <div class="fa">
      <p>inset</p>
      <p>值为(上 右 下 左 round 左上角radius 右上角radius 右下角radius 左下角radius)</p>
      <p>round前面的数值,表示的是距离,如果第一个值为25%,则表示图像在上面从25%开始绘制</p>
      <div class="inset1"></div>
      <div class="inset2"></div>
      <div class="inset3"></div>
    </div>
    
    • 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

    在这里插入图片描述
    clip-path生成器:http://tools.jb51.net/code/css3path

    11.mask(遮罩)

    核心:所谓遮罩,就是原始图片只显示遮罩图片非透明的部分。(一定要理解)
    background代表元素图片,mask代表遮罩图片
    例子1

    在这里插入图片描述

    在这里插入图片描述

    .main{
        width: 500px;
        height:500px;
        background: url('./background.png') no-repeat;
        background-size: 500px 500px;
        -webkit-mask-image: url('./mask.png');
        mask-image: url('./mask.png');
        -webkit-mask-size: 500px 500px;
        //mask-image可能无法使用,我们用其他的替换一下(用径向渐变画一个直径为250px的圆)
        //-webkit-mask: radial-gradient(transparent 250px, #000 250px) no-repeat;
        //mask: radial-gradient(transparent 250px, #000 250px) no-repeat;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    第一张图片为background(原始图片)
    第二章图片代表mask(遮罩图片)
    所以原始图片只显示大虾这张图片的非透明(也就是大虾本身)部分

    在这里插入图片描述

    例子2(做渐变)

    .main{
        width: 500px;
        height:500px;
        background: url('./background.png') no-repeat;
        background-size: 500px 500px;
        -webkit-mask: linear-gradient(90deg, #fff,transparent);
        mask: linear-gradient(90deg, #fff,transparent);
        -webkit-mask-size: 500px 500px;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述
    例子3(多张图片)

    .main{
        width: 500px;
        height:500px;
        background: url('./background.png') no-repeat;
        background-size: 500px 500px;
        position: relative;
        &::before{
            position: absolute;
            content: '';
            width: 500px;
            height: 500px;
            background: url('./overBackground.png');
            background-size: 500px 500px;
            -webkit-mask: linear-gradient(45deg, #000 50%, transparent 50%);
            mask: linear-gradient(45deg, #000 50%, transparent 50%);
            -webkit-mask-size: 500px 500px;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述
    弹幕也是这种原理
    可以分为三个图层
    1.主播的电脑桌面(游戏画面和主播的实际人物)
    2.弹幕
    3,主播实际人物的遮罩层(人物部分为透明,其他部分为非透明)
    以上述例子,弹幕为background,主播实际人物遮罩层为mask

    例子4

    .main{
        width: 500px;
        height:500px;
        background: url('./background.png') no-repeat;
        background-size: 500px 500px;
        position: relative;
    }
    .main:hover::before {
      position: absolute;
      content: "";
      width: 500px;
      height: 500px;
      background: url("./overBackground.png");
      background-size: 500px 500px;
      animation: maskRotate 2s ease-in-out;
    }
    //@for是sass的方法,没有安装sass自行修改
    @keyframes maskRotate {
      @for $i from 0 through 100 {
        #{$i}% {
     	mask: linear-gradient(
            45deg,
             #000 #{$i + "%"},
             transparent #{$i + 5 + "%"}
           );
        -webkit-mask: linear-gradient(
            45deg,
            #000 #{$i + "%"},
            transparent #{$i + 5 + "%"}
          );
        }
      }
    }
    
    • 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

    在这里插入图片描述

    引用于:
    https://juejin.cn/post/7155780555554947102
    https://www.jb51.net/css/641182.html
    https://blog.csdn.net/weixin_41897680/article/details/122688152

  • 相关阅读:
    关键短语提取的典型方法
    从零学习Linux操作系统 第三十二部分 ansible中剧本的应用
    面试突击80:说一下 Spring 中 Bean 的生命周期?
    漏刻有时API接口实战开发系列(14):身份证实名鉴权验证
    管张汇泓:一份邮件把我带到了开源世界|OneFlow U
    实力认证|万应工场荣膺2022中国低代码平台行业应用卓越奖!
    【Redis】Jedis
    2022HNCTF-web -- 部分
    CEP开发基础知识-AI|PS|AE插件-事件机制-文件操作-界面颜色
    常用数据集下载网站
  • 原文地址:https://blog.csdn.net/HelloWorldLJY/article/details/128117932