CSS 正在变得越来越疯狂!

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费积分!

作为一名旁观者,看着 CSS 的发展,我感觉我们正处于 CSS 历史上最具创新性的时刻之一。 当我们终于在所有浏览器上都实现了 flexbox 时,这确实是一件大事,没过多久,grid 也来了。 它们将 CSS 从一个笨拙的技巧集合转变为更合理、更符合时代的东西。

这种感觉一直都在加强。 就在最近,这里列出了正在发生的事情。

⚠️🤷 当这些功能真正发布时,语法可能与下面提供的代码片段不完全相同。 🤷⚠️

原生嵌套

原生嵌套已成为 第一个公开工作草案,这意味着它比以往任何时候都更接近成为现实。 许多人使用预处理器仅仅是为了嵌套的便利,而这对于那些希望简化构建工具以避免这种情况的人来说应该是有帮助的。

我特别喜欢你如何 嵌套条件规则

.card {
  & .title { }
  & .body { }

  @media (min-inline-size > 1000px) {
    & { }
  }

  @nest body.dark & { }
}

我听说过关于这种可行方案的传言,它可以避免在简单选择器上使用 &,也完全避免使用 @nest

.card {{
  .title { }
  .body { }

  body.dark & { }
}}

容器查询

容器查询目前只是一个编辑草案 (CSS Containment 模块级别 3),但它们已经在 Chrome 中实现了(带有标志)。 它们是一件大事,因为它们允许我们根据容器本身的大小做出样式决策,在当今的组件驱动型世界中,这是一个非常好的想法。

查看 代码,了解 简单的示例网站(如果你在 Chrome 中没有启用标志,可能看起来很奇怪)。

/* Set containment on the parent you're querying */
.card-container {
  /* Both work right now, not sure which is right */
  contain: style layout inline-size;
  container: inline-size;
}
.card {
  display: flex;
}
@container (max-width: 500px) {
  /* Must style a child, not the container */
  .card {
    flex-direction: column;
  }
}

容器单位

容器单位 也有 草案规范,对我来说,它几乎使容器查询的用途翻倍。 想法是,你有一个单位基于容器的大小(宽度、高度或“内联大小”/“块大小”)。 我认为 qi 单位是最有用的。

希望很快,我们将能够编写基于自身大小进行样式设置的容器范围内的 CSS,并且可以将该大小传递给其他属性在内部使用。 font-size 属性是一个简单示例,说明了它的用途(根据容器大小缩放的字体),但我相信容器单位将用于各种用途,例如 gappadding,以及谁知道还有什么其他用途。

/* Set containment on the parent you're querying */
.card-container {
  /* Both work right now, not sure which is right */
  contain: style layout inline-size;
  container: inline-size;
}
.card h2 {
  font-size: 1.5rem; /* fallback */
}
@container type(inline-size) {
  .card h2 {
    font-size: clamp(14px, 1rem + 2qi, 56px)
  }
}

层叠层

层叠层(在 工作草案规范 中)引入了一种全新的范式,用于确定 CSS 选择器在层叠中的获胜方式。 目前,这主要是一个特异性竞赛。 特异性最高的选择器获胜,只有内联样式和带有 !important 子句的特定规则才能胜过它们。 但有了层,任何在更高层上的匹配选择器都会获胜。

@layer base;      
@layer theme;   
@layer utilities; 

/* Reset styles with no layer (super low) */
* { box-sizing: border-box; }

@layer theme { 
  .card { background: var(--card-bg); }
}

@layer base { 
  /* Most styles? */
}

@layer utilities {
  .no-margin { margin: 0; }
}

@when

Tab Atkins 的 提案 用于 CSS When/Else 规则已 被接受,它提供了一种表达 @media@supports 查询的方式,使你能够更容易地表达 else 条件。 虽然媒体查询已经具备了一些 执行逻辑 的能力,但执行互斥查询一直难以表达,而这使得它变得非常简单。

@when media(width >= 400px) and media(pointer: fine) and supports(display: flex) {
  /* A */
} @else supports(caret-color: pink) and supports(background: double-rainbow()) {
  /* B */
} @else {
  /* C */
}

作用域

作用域样式(这个是 编辑草案)的想法是,它提供了一种语法来编写仅适用于某个选择器及其内部的样式块,但也具有停止作用域的能力,从而创建 作用域甜甜圈

我最喜欢的部分是“接近度”强度的东西。 Miriam 的解释如下

.light-theme a { color: purple; }
.dark-theme a { color: plum; }
<div class="dark-theme">
  <a href="#">plum</a>

  <div class="light-theme">
    <a href="#">also plum???</a>
  </div>
</div>

说得对吧? 现在没有很好的方法来表达你想要该链接与 .light-theme 的接近度获胜。 现在,由于两种主题的特异性相同,但 .dark-theme 位于后面,因此它获胜。 希望作用域样式也有助于解决这个问题。

@scope (.card) to (.content) {
  :scope {
    display: grid;
    grid-template-columns: 50px 1fr;
  }
  img {
    filter: grayscale(100%);
    border-radius: 50%;
  }
  .content { ... }
}
/* Proximity help! */
@scope (.light-theme) {
  a {
    color: purple;
  }
}

@scope (.dark-theme) {
  a {
    color: plum;
  }
}


你现在无法在生产网站上使用列表中的任何东西。 经过多年尝试跟踪这类事情,我对最终结果仍然一无所知。 我认为规范需要先完成并达成一致。 然后浏览器会采用它们,希望不止一个浏览器采用。 然后,我认为规范就可以最终确定了?

我不知道。 也许其中一些会消失。 也许其中一些会发展得非常快,而另一些则非常慢。 有可能,其中一些会在某些浏览器中发布,而在另一些浏览器中却不会发布。 嘿,至少我们现在拥有常青浏览器,因此当功能发布时,它们会很快发布。 我感觉现在我们正处于所有最强大、最好的 CSS 功能都得到所有浏览器支持的阶段,但随着这些新功能的出现,我们将进入一个阶段,对最新功能的支持将会更加零星。