我:CSS,你怎么变成紫色了?CSS:别管这些,都快2025了,这些新特性你还不知道吗?🤡

5,288 阅读13分钟

事情起因是这样的,大二的苦逼学生在给老外做页面的时候,做着做着无意间瞥见了css的图标。 image.png

wait!你不是我认识的css!你是谁? image.png

我的天呐,你怎么成了这种紫色方块?(如果只关心为什么图标换了,可以直接跳到文章末尾)

image.png

这提起了我的兴趣,立马放下手中的工作去了解。查才知道,这是有原因的,而且在这之间CSS也更新了很多新特性。

不过看了许多博客,发现没啥人说这件事(也可能是我没找到),所以到我来更新了!😄

这里主要谈谈我认为还算有点用的新特性,全文不长,如果对您有用的话,麻烦给个赞和收藏加关注呗🙏!如果可以的话,掘金人气作者评选活动给孩子投一票吧😭

先叠个甲:所有观点纯本菜🐔意淫,各位大佬地方看个乐呵就行。

参考文献:张鑫旭的个人主页 » 张鑫旭-鑫空间-鑫生活MDN Web Docs

块级元素居中新方式:Align Content for Block Elements

元素垂直居中对齐终于有了专门的CSS属性,之前Flex布局和Grid布局中使用的align-content属性,现在已经可以在普通的block块级元素中使用。

垂直居中的快级元素不再需要 flex 或 grid,注意是在垂直居中!!!

      display: block; <-非块级元素请加上这个代码
      align-content: center;

不过我好像以前用过,不过用的很少,不知道是不是发生了改变造成了这种效果🤡

请看如下代码

  <style>
    .father {
      display: block;
      align-content: center;
      background-color: aqua;
      width: 300px;
      height: 300px
    }

    .son {
      width: 100px;
      height: 100px;
      background-color: red;
    }
  </style>

可以发现是div是垂直居中显示的

image.png

实现效果和用flex是一样的

  <style>
    .father {
      display: flex;
      align-item:center
      background-color: aqua;
      width: 300px;
      height: 300px
    }

    .son {
      width: 100px;
      height: 100px;
      background-color: red;
    }
  </style>

image.png

提醒一下,目前普通元素并不支持justify-content属性,必须Flex布局或者Grid布局。

subgrid

额,这个特性似乎国内没有很多文章讲解,但是我记得之前看过一个统计这个特性在老外那里很受欢迎,所以我还是讲解一下。

subgrid并不是一个CSS属性,而是 grid-template-columnsgrid-template-rows属性支持的关键字,其使用的场景需要外面已经有个Grid布局,否则……嗯,虽然语法上不会识别为异常,但是渲染结果上却是没有区别的。

例如

.container {
    display: grid;
}
.item {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: subgrid;
}

那我们什么时候使用它呢?🤔

当我们想实现这种效果

image.png Grid布局负责大的组织结构,而里面更细致的排版对齐效果,则可以使用subgrid布局。,这对于复杂的嵌套布局特别有用,在 subgrid 出现之前,嵌套网格往往会导致 CSS 变得复杂冗长。(其实你用flex也可以) 子网格允许子元素与父网格无缝对齐,从而简化了这一过程。

    .container {
      display: grid;
      gap: 1rem;
      grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    }
    .item {
      display: grid;
      grid-template-rows: subgrid;
      grid-row: span 4;
      gap: .5rem;
    }
    /* 以下CSS与布局无关 */
    .item {
      padding: .75rem;
      background: #f0f3f9;
    }
    .item blockquote {
      background-color: skyblue;
    }
    .item h4 {
      background-color: #333;
      color: #fff;
    }
  <div class="container">
    <section class="item">
      <h4>1</h4>
      <p>负责人:张三</p>
      <blockquote>脑子和我只能活一个</blockquote>
      <footer>3人参与 12月21日</footer>
    </section>
    <section class="item">
      <h4>1</h4>
      <p>负责人:张三</p>
      <blockquote>脑子和我只能活一个</blockquote>
      <footer>3人参与 12月21日</footer>
    </section>
  </div>

效果 image.png

@property

@property规则属于CSS Houdini中的一个特性,可以自定义CSS属性的类型,这个特性在现代CSS开发中还是很有用的,最具代表性的例子就是可以让CSS变量支持动画或过渡效果。

我个人认为这个东西最大的作用就是在我们写颜色渐变的时候很好避免使用var()不小心造成颜色继承的,而导致效果不理想。

用法

@property --rotation {
  syntax: "<angle>";
  inherits: false;
  initial-value: 45deg;
}

描述符

  • syntax 描述已注册自定义属性允许的值类型的字符串。可以是数据类型名称(例如<color><length><number>等),带有乘数(+#)和组合符(|),或自定义标识。

  • inherits 一个布尔值,控制指定的自定义属性注册是否默认@property继承。

  • initial-value设置属性的起始值的值。

描述

注意

  • 规则@property必须同时包含syntaxinherits描述符。如果缺少其中之一,则整个@property规则无效并被忽略。
  • 未知描述符无效并会被忽略,但不会使@property规则无效。

简单演示

    @property --box-pink {
    syntax: "<color>";
    inherits: false;
    initial-value: pink;
    }
    .box {
      width: 100px;
      height: 100px;
      background-color: var(--box-pink);
    }

image.png

使用它进行颜色渐变

    @property --colorA {
  syntax: "<color>";
  inherits: false;
  initial-value: red;
}

@property --colorB {
  syntax: "<color>";
  inherits: false;
  initial-value: yellow;
}

@property --colorC {
  syntax: "<color>";
  inherits: false;
  initial-value: blue;
}



.box {
  width: 300px;
  height: 300px;
  background: linear-gradient(45deg,
              var(--colorA),
              var(--colorB), 
              var(--colorC));
  animation: animate 3s linear infinite alternate;
}

@keyframes animate {
  20% {
    --colorA: blue;
    --colorB: #F57F17;
    --colorC: red;
  }

  40% {
    --colorA: #FF1744;
    --colorB: #5E35B1;
    --colorC: yellow;
  }

  60% {
    --colorA: #E53935;
    --colorB: #1E88E5;
    --colorC: #4CAF50;
  }

  80% {
    --colorA: #76FF03;
    --colorB: teal;
    --colorC: indigo;
  }
}

  </style>

Recording%202024-12-20%20230242_converted.gif

transition-behavior让display none也有动画效果

大家都知道我们在设置一个元素隐藏和出现是一瞬间的,那有没有办法让他能出现类似于淡入淡出的动画效果呢?

这里我们就要介绍transition-behavior了,但是也有其他方法,这里就只介绍它。 语法如下:

transition-behavior: allow-discrete;
transition-behavior: normal;
  • allow-discrete表示允许离散的CSS属性也支持transition过渡效果,其中,最具代表性的离散CSS属性莫过于display属性了。

使用案例

仅使用transition属性,实现元素从 display:inline ↔ none 的过渡效果。

    img {
      transition: .25s allow-discrete;
      opacity: 1;
      height: 200px;
    }
    img[hidden] {
      opacity: 0;
    }
  <button id="trigger">图片显示与隐藏</button>
  <img id="target" src="./1.jpg" />
  trigger.onclick = function () {
    target.toggleAttribute('hidden');
  };

Recording%202024-12-21%20013159_converted.gif 这里我们可以发现消失的时候是有淡出效果的,但是出现却是一瞬间的,这是为什么?

原因是: display:nonedisplay:block的显示是突然的,在浏览器的渲染绘制层面,元素display计算值变成block和opacity设为1是在同一个渲染帧完成的,由于没有起始opacity,所以看不到动画效果。

那有没有什么办法能解决呢?🤔

使用@starting-style规则声明过渡起点

@starting-style顾名思义就是声明起始样式,专门用在transition过渡效果中。

例如上面的例子,要想让元素display显示的时候有淡出效果,很简单,再加三行代码就可以了:

img {
    transition: .25s allow-discrete;
    opacity: 1;
    @starting-style {
      opacity: 0;
    }
}

或者不使用CSS嵌套语法,这样写也是可以的:

img {
  transition: .25s allow-discrete;
  opacity: 1;
}
@starting-style {
  img {
    opacity: 0;
  }
}

此时,我们再点击按钮让图片显示,淡入淡出效果就都有了。

Recording%202024-12-21%20013930_converted.gif

注意:@starting-style仅与 CSS 过渡相关。使用CSS 动画实现此类效果时,@starting-style就不需要。

light-dark

先说明一下,我认为 CSS 的新 light-dark() 函数是 2024 年实现暗模式的最佳方式!

你自 2019 年以来,开发人员只需一行 CSS 就可以为整个站点添加暗模式?只需在 :root 中添加 color-scheme: light dark;,就可以获得全站暗模式支持——但它只适用于未指定颜色的元素,因此使用默认的浏览器颜色。

如果你想让自定义颜色的暗模式生效(大多数网站都需要),你需要将每个颜色声明包装在笨拙的 @media (prefers-color-scheme: ...) 块中:

@media (prefers-color-scheme: dark) {
 body {
 color: #fff;
 background-color: #222;
 }
}

@media (prefers-color-scheme: light) {
 body {
 color: #333;
 background-color: #fff;
 }
}

基本上,你需要把每个颜色声明写两遍。糟糕!这种冗长的语法使得编写和维护都很麻烦。因此,尽管 color-scheme 已发布五年,但从未真正流行起来。

light-dark很好解决了这个问题

基本语法

/* Named color values */
color: light-dark(black, white);

/* RGB color values */
color: light-dark(rgb(0 0 0), rgb(255 255 255));

/* Custom properties */
color: light-dark(var(--light), var(--dark));
body {
 color-scheme: light dark; /* 启用浅色模式和深色模式 */
 color: light-dark(#333, #fff); /* 文本浅色和深色颜色 */
 background-color: light-dark(#fff, #222); /* 背景浅色和深色颜色 */
}

在这个示例代码中,正文文本在浅色模式下定义为 #333,在深色模式下定义为 #fff,而背景色则分别定义为 #fff 和 #222。就这样!浏览器会根据用户的系统设置自动选择使用哪种颜色。

无需 JavaScript 逻辑、自定义类或媒体查询。一切都能正常工作!

:user-vaild pseudo class

:user-validCSS伪类表示任何经过验证的表单元素,其值根据其验证约束正确验证。然而,与:valid此不同的是,它仅在用户与其交互后才匹配。

有什么用呢?🤔

这就很好避免了我们在进行表单验证的时候,信息提示在你交互之前出现的尴尬。

  <form>
    <label for="email">Email *: </label>
    <input
      id="email"
      name="email"
      type="email"
      value="test@example.com"
      required />
    <span></span>
  </form>  
input:user-valid {
  border: 2px solid green;
}

input:user-valid + span::before {
  content: "😄";
}

在以下示例中,绿色边框和😄仅在用户与字段交互后显示。我们将电子邮件地址更改为另一个有效的电子邮件地址就可以看到了

image.png

interpolate-size

interpolate-sizecalc-size()函数属性的设计初衷是一致的,就是可以让width、height等尺寸相关的属性即使值是auto,也能有transition过渡动画效果。

最具代表性的就是height:auto的过渡动画实现。

    p {
      height: 0;
      transition: height .25s;
      overflow: hidden;
    }

    .active+p {
      height: auto;
      height: calc-size(auto, size);
    }
  <button onClick="this.classList.toggle('active');">点击我</button>
  <p>
    <img src="./1.jpg" width="256" />
  </p>

其实,要让height:auto支持transition过渡动画,还有个更简单的方法,就是在祖先容器上设置:

interpolate-size: allow-keywords;

换句话说,calc-size()函数是专门单独设置,而interpolate-size是全局批量设置。

interpolate-size: allow-keywords;
interpolate-size: numeric-only;
/* 全局设置 */
    /* :root {
    interpolate-size: allow-keywords;

    } */
    div {
      width: 320px;
      padding: 1em;
      transition: width .25s;
      /* 父级设置 */
      interpolate-size: allow-keywords;
      background: deepskyblue;
    }

    .active+div {
      width: 500px;
    }
  </style>
  <button onClick="this.classList.toggle('active');">点击我</button>
  <div>
    <img src="./1.jpg" width="256" />
  </div>

Recording%202024-12-21%20002244_converted.gif

全新的CSS相对颜色语法-使用from

from的作用我认为是简化了我们让文字自动适配背景色的步骤

我们先来看看用法

p {
  color: rgb(from red r g b / alpha);
}

image.png

原因:r g b 以及 alpha 实际上是对red的解构,其计算值分别是255 0 0 / 1(或者100%)。

注意:实际开发,我们不会使用上面这种用法,这里只是为了展示语法作用。

使用from让文字适配背景色

<button id="btn" class="btn">我是按钮</button>

<p>请选择颜色:<input 
  type="color" 
  value="#2c87ff" 
  onInput="btn.style.setProperty('--color', this.value);"
></p>
<p>请选择颜色:<input 
  type="color" 
  value="#2c87ff" 
  onInput="btn.style.setProperty('--color', this.value);"
></p>

Recording%202024-12-21%20004850_converted.gif

rebecca purple(#663399)

好了,最重要的东西来了,关于为什么变成了紫色,其实他们把它叫做rebecca紫,为什么叫这个名字呢?这其实是一个令人悲伤的故事😭。

在关于css这个新颜色以及logo的时候,内部发生了许多争议。

但是相信大部分人都读过CSS The Definitive guide,他的作者Eric A.Myer的女儿在这期间因为癌症去世了 在她去世的前几周,Rebecca说她即将成为一个六岁大的女孩,而becca是一个婴儿的名字。六岁后,他希望每个人都叫他Rebecca,而不是becca。

而那个女孩和病魔抗争,一直坚持到她到六岁, 我无法想象假如我是父亲,失去一个那么可爱的一个六岁的孩子,那个心情有多么痛苦。

最终社区被他的故事感动了,css的logo也就变成了这样。

总结

新特性多到让人麻木,真的非常非常多!!!!😵‍💫 这些新特性出现的速度比某四字游戏出皮肤的速度还快🚀,关键这些特性浏览器支持情况参差不齐,短时间无法在生产环境应用。

我真的看了非常都非常久,从早上五点起来开始看文档,除去吃饭上课,加上去写文章一直弄到凌晨三点,才选出这么几个我认为还算有点作用的新特性。

而且现有的JavaScript能力已经足够应付目前所有的交互场景,很多新特性没有带来颠覆性的改变,缺少迫切性和必要性,很难被重视。

最后的最后,希望大家的身边的亲人身体都健健康康的,也希望饱受癌症折磨的人们能够早日康复🙏