conclude

Modern Css Experience

如果你问一个前端开发者三板斧中哪一项最让人头疼 不同阶段的人回答会有所不同

但无论是对于新手还是老师傅来说css都是那个让人又爱又恨的存在

并且css也陆续有新特性出现 许多备受期待的特性也受到了主流浏览器的支持让开发者可以安心使用

本文将对一些新的或者说平时不怎么关注的特性进行梳理

希望可以开阔一些想法 灵活运用更多知识

如果想要了解更多 也可以移步至大佬博客


视口单位

概念

视口单位vw vh的概念直观地展示了视口的宽高

但是在移动设备上情况会有所不同 首先在移动设备上会分为大小两种视口
在这里插入图片描述

也就是图片中的svh lvh 100vh趋向于匹配lvh

如果想要达到动态切换svh/lvh的效果 就需要使用dvh

兼容性

在这里插入图片描述


颜色相关

简写

/* 不用再写,啦 */
background-color: rgb(255 255 0)
background-color: lab(0% 0 0)
background-color: hwb(206 0% 42%)

lab()

lab函数可以从 CIELAB color space 获取整个色域范围

如今显示器可以显示比sRGB色彩空间更多的颜色 我们可以通过lab()来访问

接受三个值 lab(lightness a-axis b-axis)

lightness代表亮度 通常来说是0%~100% 也可能到达400%表示超级亮的白色

后两个参数表示色调 理论上无界 但实际上[-160,160]

在这里插入图片描述

hwb()

与前者类似

hwb(hue whitness blackness / alpha) => 色调 白度 灰度 / 透明度

在这里插入图片描述

conic-gradient()

可用该函数创建围绕中心点选中的颜色渐变

/* 
	1. 默认情况下  从0度开始顺时针旋转
	2. 可设置旋转角度
	3. 可以设置偏离原心的点(单位 百分比 关键字left/center等)
	4. 控制渐变范围
*/
div {
  background-image: conic-gradient(aqua, fuchsia, salmon, aqua);  
}

div {
  background-image: conic-gradient(from 90deg, aqua, fuchsia);  
}

div {
  background-image: conic-gradient(from 90deg at 4rem 4rem, aqua, fuchsia);
}

div {
  background-image: conic-gradient(aqua 0deg 50deg, fuchsia 80deg 100deg, salmon 130deg 140deg, aqua 360deg)
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EXvkNwKd-1688003274001)(C:\Users\恰比\AppData\Roaming\Typora\typora-user-images\image-20230627223722786.png)]

color-scheme

使用该属性可以更改浏览器默认的配色方案

注意并非是像想的那样全部改变 而是有一定的作用范围

包括 表单控件 滚动条 CSS系统颜色

表单控件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nIwgAERf-1688003274001)(C:\Users\恰比\AppData\Roaming\Typora\typora-user-images\image-20230628101543542.png)]

单独对某个表单元素直接使用

select {
	color-scheme: dark;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZTUqqBkV-1688003274002)(C:\Users\恰比\AppData\Roaming\Typora\typora-user-images\image-20230628101727329.png)]

其它表单的深色模式对比

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-69JQFgW8-1688003274003)(C:\Users\恰比\AppData\Roaming\Typora\typora-user-images\image-20230628101856342.png)]

滚动条

MDN官网

在这里插入图片描述

系统颜色

以button为例 其默认样式中使用到了一些系统颜色

这些颜色会根据color-scheme自动适应深色模式

button{
  color: buttontext;
  background-color: buttonface;
  border-color: buttonborder;
}

并且这些元素可以在普通元素中使用 这样普通颜色也能使用这些值做到自适应

兼容性

在这里插入图片描述


自定义属性

使用

通过var来使用

        :root {
            --main-bg-color: pink;
        }

        body {
            background-color: var(--main-bg-color);
        }

var()中还可以传入回退值 如果第一个值没有定义 会使用该回退值

.item1 {
	background-color: var(--not-set, #000);
}

回退值中也可以使用var()

	.item2 {
		background-color: var(--not-set, var(--also-not-set, #00f));
	}

值的忽略

.item3 {
	background-color: #F00;
	/* 无效值被忽略 */
	background-color: blahaha;
}

如果第二个声明是不存在的自定义属性 此时不会被忽略 而是使用继承值

.item4 {
	/*第二个声明是不存在的自定义属性 此时不会被忽略 使用继承值*/
	background-color: #F00;
	background-color: var(--not-set);
}

自定义属性中的优先级

normal vs custom

        .example {
            /* 
            	自定义属性后面有!important的话 会被解析器移除该关键字 所以后面的属性就会覆写
            */
            --color: red !important;
            color: var(--color);
            color: blue;
        }

        .example3 {
            /* 最后还是blue */
            --color: red !important;
            --color: blue;

            color: var(--color);
            color: blue;
        }

custom

        .example1 {
            /* 一样优先级的话会像普通属性那样后面覆盖前面 */
            --color: red;
            --color: blue;
            color: var(--color);
        }

        .example2 {
            /* 都是自定义属性的话 可以用!important来改变权重 */
            --color: red !important;
            --color: blue;

            color: var(--color);
        }

自定义url

场景: 点击按钮时切换背景图片

首先抛出一种错误写法 url()的参数中没有"" or ''时 并非传入一个string 而是需要转义的url-token

        button {
            --background-image: "/not-pressed.svg";
            background: url(var(--background-image));
        }

        button[aria-pressed="true"] {
            --background-image: "/pressed.svg";
        } 

正确写法

        button {
            --background-image: url("/not-pressed.svg");
            background: var(--background-image);
        }

        button[aria-pressed="true"] {
            --background-image: url("/pressed.svg");
        }

简写与逻辑属性

全局属性dir 可以用来指明元素中文本方向

其值为逻辑属性 ltr rtl auto

在这里插入图片描述

margin

margin-inline margin-block都为简写属性

分别代表水平方向与竖直方向的值

接收1-2个value 2个value时则表示(start - end)

此时回考虑direction 也就是dir定义的

padding

与margin一致

inset

它也是简写属性 代替定位时四个方向都要赋值的写法

同样具有逻辑属性 inset-inline inset-block

在绝对定位中让子元素填充满父元素

        .outer {
            border: 10px solid hotpink;
            position: relative;
            width: 7rem;
            height: 7rem;
        }
        .inner {
            position: absolute;
            inset: 0;
            background-color: aqua;
            z-index: 99;
        }

在固定定位中填充视口

        .inner_f {
            position: fixed;
            inset: 0;
            background: #008c8c;
        }

函数

min() and max()

接受以逗号分隔的一系列值 取最小/最大的那个

但是使用静态值意义不大 正确用法是配合相对单位使用

div {
	/* 表示最大值为800px 小于800时自适应 */
	width: min((100%, 800px))
}

	
.wrapper {
    /* 宽度自适应的居中展示 最大宽度为64rem*/
	height: 100px;
	margin-inline: max(0px, ((100% - 64rem) / 2));
	background-color: rgb(255 255 0);
}

clamp()

clamp(minmum, preferred, maxmum) 定义了三个值

clamp(300px, 90%, 700px) => max(300px, min(90%, 700px))

表示可以在[300px,700px]直接自适应


伪类

:has()

:has()目前来说仅在Firefox中缺失 但是它在一个标志后面 很快就能得到支持

检测父元素是否包含一个特定的子元素

	/* 如果.form-item包含aria-invalid = "true"属性的子元素 */
        .form-item:has([aria-invalid="true"]) {
            --color: #caf;
        }
	/* 如果div包含p元素 */
        div:has(p) {
            margin-top: 10px;
            border: 4px solid var(--color);
        }

注意这样嵌套的写法是无效的

div:has(p:has(strong)) {
    /* 无效 */
}

/* 正确写法 */
div:has(p strong){
	border: 2px solid yellow;
}

权重

        /* 这两个权重一样 */
        div.child {
            background-color: #caf;
        }
        div:has(.hh) {
            background-color: green;
        }

与组合器使用

        /* 与 > 组合 */
        fieldset:not(:has(> legend)) {
            border: 10px solid red;
        }
        /* 与 + 组合 */
        h2 {
            margin-block-end: 0.7em;
        }
        h2:has(+ time){
            margin-block-end: 0;
        }

选中特定个数的子项 >= 3 / =3

        ul:has(>:nth-child(3)){
            border: 10px solid yellow;
        }

        ul:has(>:nth-child(3):last-child){
            border: 10px solid blue;
        }

:has(:not()) :not(:has())

       /* 选中的元素不含img元素 */
		.right:not(:has(img)) {
            border-style: dotted;
        }
		/* 选中的元素含有除了img元素以外的任意元素 */	
        .wrong:has(:not(img)) {
            border-style: dotted;
        }

:is() :where()

这两个伪类用于以更紧凑的形式书写选择器

        input:where([type="text"],
            [type="email"],
            [type="url"],
            [type="tel"],
            [type="password"],
            [type="search"]) {
            border: 2px solid;
        }

两者区别

:where不会增加权重 button:where(.button1) => button

:is()则会 button:is(.button1) => button.button1

        /* case  */
        .where input:where([type="text"], [type="email"], [type="url"]) {
            background-color: #efefef;
            border: 2px solid;
        }

        .where [aria-invalid="true"] {
            border-color: red;
        }

forgiving-selectors

当我们使用选择器列表时 其中一项无效或不存在或浏览器不支持

那这个列表所有选择器都会失效

这时候可以用 :has() :where() :is() 它们会自动忽略列表中无效的那个选择器

:modal

modal伪类用于控制showModal打开后的样式

::backdrop()可控制背景样式

        :modal {
            border-style: dashed;
            border-color: red;
            padding: 4rem;
            background-color: lab(62% 30 24);
        }
		::backdrop {
    		background-color: lab(62% 30 24/40%);
		}

在这里插入图片描述

:placeholder-shown

选中还没改变placeholder的输入框


其它

scrollbar-gutter

该属性允许为滚动条保留空间 避免因内容增长引起的布局改变 避免不需要滚动时出现不必要的效果

stable - 预留空间 这样文字也会更加紧凑 同时该元素必须是overflow

放在body无效 推荐放到html

stable both-edges - 文字居中 两侧预留

在这里插入图片描述

font-variation-settings

用于调节可变字体的 weight width

        p {
            font-family: 'Saira', sans-serif;
            font-size: 2rem;
            font-variation-settings: 'wght' 736, 'wdth' 360;
        }

可以去 这里 直观感受一下

aspect

aspect用来定义宽高比 如果同时写了两个值 aspect-ratio: auto 3 / 1

可替换元素会使用固有的比例 其它元素会使用3 / 1

如果元素的高度超过了定义的高度 此时可以使用overflow:auto

在这里插入图片描述

overscroll-behavior

作用于这种嵌套滚动的场景
在这里插入图片描述

当内部滚动区域到底部以后 再滚动会影响外部的滚动区域

如果希望滚动不会像链式那样 可以使用overscroll-behavior: none

container queries

使用它可以让任何父元素达到媒体查询那样的功能

不止是宽度 还可以有高度 方向 自定义属性

但对于容器尺寸相关与容器样式相关的属性 有一个重要的区别

尺寸容器需要明确定义 才会发挥作用

container-type 有两个值 inline-sizesize 没有block-size

需要注意的是 container中的width总是指代content-box

/* That's our size container. */
section {
  width: 50%;
  container-type: inline-size;
}

/* width超过500px时触发 */
@container (min-width: 500px) {
  .card {
    background-color: hotpink;
  }
}

explicit property

  • inherit: 从parent那继承定义好的属性值
  • innitial: 将属性设置为初始值 注意初始值并不是默认值
  • unset: 可继承属性继承自parent 否则使用初始值
  • revert: 可继承属性继承自parent 否则用上一个级联层的值 如default值等 如果还是没有就initial值

transform

transform的值可独立存在 这样发生改变时不必所有都写

        button {
            translate: 20px 0;
            rotate: 15deg;
            scale: 1;
        }
        button:is(:hover, :focus) {
            scale: 2;
        }

backdrop-filter

将CSS过滤器应用于元素后面的区域 可以是元素或对话框的背景

并且不会影响文字 这是与filter的差异

        .parent {
            /**/
            background-image: url("https://assets.codepen.io/144736/neue-donau+%281%29.webp");
        }

        .blur {
            backdrop-filter: blur(5px);
        }

        .invert {
            backdrop-filter: invert(1);
        }

        .hue {
            backdrop-filter: hue-rotate(260deg);
        }

        .grayscale {
            backdrop-filter: grayscale(100%);
        }

在这里插入图片描述

@layer

@layer声明了一个级联层 同一层内的规则将级联在一起

不同级联层之间的权重不会相互干扰 即优先级高的级联层 其权重永远大于优先级低的级联层

  • @layer X {} - 这种情况后面的优先级高于前者

            /* red */
    		@layer A {
                .layer {
                    background-color: blue;
                }
            }
            @layer B {
                div {
                    background-color: red;
                }
            } 
    
  • 用@layer X, Y, Z提前声明 - 优先级 Z > Y > X 不看之后的书写顺序

    • 如果一个layer被多次定义 只有第一次出现有效
    		/* blue */
    		@layer B,C,A
            @layer A {
                div {
                    background: blue;
                }
            }
            @layer B {
                div {
                    background: green;
                }
            }
            @layer C {
                div {
                    background: orange;
                }
            } 
    
  • 非 @layer 包裹的样式 拥有比 @layer 包裹样式更高的优先级

            /* green */
    		a {
                color: green;
            }
    
            @layer A {
                a {
                    color: red;
                }
            }
    
            @layer B {
                a {
                    color: orange;
                }
            }
    
    
  • 嵌套层

    • 无论是否存在嵌套 优先级都整体比优先级低的 @layer高
    • 嵌套层 @layer A > @layer A.B
            /* res => @layer C > @layer C.D > @layer A > @layer A.B */
    			@layer A {
                div {
                    background: blue;
                }
    
                @layer B {
                    div {
                        background: red;
                    }
                }
            }
    
            @layer C {
                div {
                    background: yellow;
                }
    
                @layer D {
                    div {
                        background: green;
                    }
                }
            }
    
  • revert-layer

    • 在嵌套的layer中 revert-layer 可回滚样式到上一层layer
  • 实际使用

    我们需要引入第三方库的 CSS 为了便于管理 或者便于覆盖其中的一些样式

    在之前 只能通过写优先级更高的class去覆盖 或者通过!important去覆盖

有了 @layer 之后 可以这样写:

@import(elementUI.css) layer(elementUI); @import(page.css) layer(page);
		@layer A {
          div {
              background: blue;
          }

          @layer B {
              div {
                  background: red;
              }
          }
      }

      @layer C {
          div {
              background: yellow;
          }

          @layer D {
              div {
                  background: green;
              }
          }
      }

- revert-layer

- 在嵌套的layer中 revert-layer 可回滚样式到上一层layer

- 实际使用

>我们需要引入第三方库的 CSS 为了便于管理 或者便于覆盖其中的一些样式 
>
>在之前 只能通过写优先级更高的class去覆盖 或者通过!important去覆盖

有了 @layer 之后 可以这样写:

```css
@import(elementUI.css) layer(elementUI); @import(page.css) layer(page);

只要在page.css 里面写的样式 优先级都会比 elementUI.css 内的 CSS 优先级更高

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nasuke_D

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值