乐趣区

关于前端:CSS新规范样式查询

本文首发于微信公众号:大迁世界, 我的微信:qq449245884,我会第一工夫和你分享前端行业趋势,学习路径等等。
更多开源作品请看 GitHub https://github.com/qq449245884/xiaozhi,蕴含一线大厂面试残缺考点、材料以及我的系列文章。

快来收费体验 ChatGpt plus 版本的,咱们出的钱
体验地址:https://chat.waixingyun.cn
能够退出网站底部技术群,一起找 bug.

最近,Chrome 团队公布了对一个新的 CSS 标准的实验性反对,即 款式查问。简而言之,它让咱们查问容器的款式,而不是只查问尺寸。在查问容器尺寸不够的状况下,这可能很有帮忙。

CSS 容器查问

介绍款式查问之前,咱们先来回顾容器查问。

CSS 容器查问(Container Queries)是一项新的 CSS 性能,容许开发人员依据元素的大小来利用款式。这意味着,开发人员能够为不同大小的设施或浏览器窗口利用不同的款式,而无需应用媒体查问或应用 JavaScript 来检测设施大小。

咱们来看看一个例子:

.o-grid__item {container-type: inline-size;}

.c-article {/* The default style */}

@container (min-width: 400px) {
  .c-article {
    /* The styles that will make the article horizontal**
    ** instead of a card style.. */
  }
}

首先,咱们须要在定义 container-type。而后,应用 @container开始查问。一旦满足了这个条件,CSS 将利用于该容器内的组件。

款式查问

简略地说,款式查问让咱们查问一个容器的 CSS 属性或 CSS 变量。

款式查问依然是试验性的,目前只在 Chrome Canary 中实现。要测试它们,请进入 chrome://flags 并激活 “Experimental Web Platform features” 的切换。

例如,咱们能够查看容器是否有 display: flex,并在此基础上为子元素设计款式。

.page-header {display: flex;}

@container style(display: flex) {
  .page-header__start {
    flex: 1;
    display: flex;
    align-items: center;
    border-right: 1px solid lightgrey;
  }
}

现实状况下,上述做法应该是可行的,但目前 Chrome Canary 中的款式查问原型仅局限于 CSS 变量。款式查问预计将在 Chrome M111 中呈现。

当初,咱们能够查看变量 --boxed: true 是否被增加到容器中,如果是,咱们能够在此基础上扭转子元素的款式。

请看下图:

请留神,容器查问和款式查问的次要区别在于,前者是针对大小的查问,后者是针对款式的查问。

.card-container {--boxed: true;}

@container style(--boxed: true) {
  .card {/* boxed styles */}
}

问题

在探讨咱们能够在哪里应用款式查问之前,咱们先来答复大家常见的一个问题:款式查问能解决什么问题?容器查问还不够吗?

这是一个好问题。在容器查问中,咱们能够依据一个组件的父级宽度来管制它的款式,这十分有用。不过,在某些状况下,咱们可能不须要查问尺寸,而是想查问一个容器的计算款式。

为了让你有更好的理解,请看下图:

这是一篇来自 CMS 的文章正文。咱们有一个默认的图片款式和另一个看起来有特色的款式。

上面是对应的代码:

<figure>
  <img src="cheesecake.jpg" alt="" />
  <figcaption>....</figcaption>
</figure>
figcaption {
  font-size: 13px;
  padding: 4px 8px;
  background: lightgrey;
}

当咱们开始对特色的进行造型时,咱们须要笼罩上述内容,并有一个 CSS 类,咱们能够用它进行造型。

.featured-figure {
  display: flex;
  flex-wrap: wrap;
}

.featured-figure figcaption {
  font-size: 16px;
  padding: 16px;
  border-left: 3px solid;
  margin-left: -6rem;
  align-self: center;
}

当咱们开始为突出显示的元素增加款式时,咱们须要笼罩上述款式并定义一个 CSS 类,以便能够对其进行款式设置。

.featured-figure {
  display: flex;
  flex-wrap: wrap;
}

.featured-figure figcaption {
  font-size: 16px;
  padding: 16px;
  border-left: 3px solid;
  margin-left: -6rem;
  align-self: center;
}

很酷,这个办法行。咱们能不能做得更好?是的!应用款式查问,咱们能够在 figure 中增加 display: flex 或一个 CSS 变量 --featured: true,而后基于这个进行款式设置。

<figure>
  <img src="cheesecake.jpg" alt="" />
  <figcaption>....</figcaption>
</figure>
figure {
  container-name: figure;
  --featured: true;
}

/* Featured figure style. */
@container figure style(--featured: true) {
  img {/* Custom styling */}

  figcaption {/* Custom styling */}
}

如果 --featured: true 不存在,咱们将默认应用根本 figure 设计。咱们能够应用 not 关键字来查看 figure 是否没有 display: flex

/* Default figure style. */
@container figure not style(--featured: true) {
  figcaption {/* Custom styling */}
}

要晓得的几个细节默认状况下,每个元素都是款式容器

所以基本不须要定义一个款式容器。默认状况下,它就在那里。

咱们不能用类名来解决这个问题吗?

是的,咱们能够。应用款式查问的目标是使 CSS 更易读并更容易批改。上述逻辑能够作为一个组件 CSS 写出,而无需将所有这些款式增加到条件类中。

事例:https://codepen.io/shadeed/pen/ZERZxzG/a583817975bae6b78308ac…

缩小 CSS 特定性问题

我喜爱应用款式查问的起因是,它将缩小 CSS 特定性,因为咱们将不太依赖 CSS 变动类或 HTML 数据属性来对组件变动进行款式设置。

在上面的 CSS 中,咱们为 section 增加了根本款式。没有什么特地的。

.section {background-color: lightgrey;}

.section__title,
.section__desc {color: #222;}

咱们须要一种办法来为它设置不同的主题,因而咱们应用了变动类。

.section--dark {background-color: #222;}

.section--dark .section__title,
.section--dark .section__desc {color: #fff;}

应用款式查问,咱们能够在 .section 组件四周应用容器,而后在不在 CSS 中创立更多特定性的状况下为题目和形容打标签。

@container style(--theme: dark) {
  .section {background-color: #222;}

  .section__title,
  .section__desc {color: #fff;}
}

这看起来洁净多了。

接下来,咱们摸索几种款式查问可能有帮忙的应用状况。

应用状况和示例

基于上下文的款式设置

这是一种常见的应用状况,在同一包装器中咱们应用了雷同的组件但用法不同。在右侧,咱们有一个文章组件,可能蕴含一个数字或不蕴含。

目前,咱们可能会应用一个新的 CSS 类来解决款式设置问题,或者可能在文章组件自身上应用变动类。

.most-popular {counter-reset: list;}

.most-popular article {/* custom styling */}

或者咱们可能在 HTML 中应用 data 属性。

.most-popular[data-counter="true"] {counter-reset: list;}

.most-popular[data-counter="true"] .article {/* custom styling */}

应用 CSS 款式查问,咱们能够在父元素中增加一个 CSS 变量,并依据此对文章进行款式设置。看看这个:

.most-popular {--counter: true;}

@container style(--counter: true) {
  .articles-list {counter-reset: list;}

  .article {
    display: flex;
    align-items: flex-start;
  }

  .article:before {
    counter-increment: list;
    content: counter(list);
  }
}

咱们甚至不须要在文章组件上应用变动类。也不须要应用 CSS 嵌套。

示例:https://codepen.io/shadeed/pen/LYBYYWP/b53e0baa891dc48b0689e1…

组件级的主题切换

咱们构建的一些组件依据特定条件须要应用不同的主题。在上面的示例中,咱们有一个蕴含不同统计组件的仪表板。

基于包装器,咱们须要切换组件的主题。

目前,咱们能够应用非凡类依据它们的容器为自定义统计组件增加款式。

.special-wrapper .stat {background-color: #122c46;}

.special-wrapper .stat__icon {background-color: #2e547a;}

.special-wrapper .stat__title {background-color: #b3cde7;}

下面的做法一点也没有错,也不坏,但因为咱们嵌套了 CSS,所以减少了特殊性。让咱们探讨一下如何用款式查问来实现上述内容。

首先,咱们须要在非凡包装器上定义一个切换按钮。而后,咱们能够查看该开关是否处于激活状态,并对状态组件进行相应的设计。

.special-wrapper {
  --theme: dark;
  container-name: stats;
}

@container stats style(--theme: dark) {
  .stat {/* Add the dark styles. */}
}

在这种状况下,款式查问的有用之处在于,将上述款式放在 CSS 中的一个中央是有意义的。

/* stat.css */
.stat {/* default styling */}

@container stats style(--theme: dark) {
  .stat {/* custom styling */}
}

头像组

在这个例子中,咱们有一组用户的头像。咱们须要依据在父代上设置的一个 CSS 变量,以不同的形式来安排它们。我从 Atlassian 设计零碎中筛选了这个例子。

<div class="avatars-wrapper">
  <div class="avatars-list">
    <div class="avatar"></div>
    <!-- more avatars -->
  </div>
</div>

在 CSS 中,我给容器增加了一个名字,并定义了 --appearance: default 变量。

.avatars-wrapper {container-name: avatars;}

.avatars-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}

有了这个,咱们就能够应用款式查问来扭转基于 --appearance 变量的布局。

@container avatars style(--appearance: stack) {
  .avatar {box-shadow: 0 0 0 2px #fff;}

  .avatar + .avatar {margin-inline-start: -0.5rem;}
}

@container avatars style(--appearance: grid) {
  .avatars-list {
    gap: 0.5rem;
    max-width: 200px;
  }
}

地址:https://codepen.io/shadeed/pen/KKeYLXG/464bd92260d290df58e138…

条件装璜款式

在某些状况下,咱们可能须要依据文本元素在 HTML 中的地位为其增加条件装璜款式。

题目和段落下方有一个旋转的背景成果。这是通过伪元素实现的:

<div class="content">
  <h2><!-- Title here --></h2>
  <p><!-- Description --></p>
</div>

要对它们进行款式设置,咱们能够应用 CSS 变量并查看它是否已切换,而后相应地增加款式。在示例中,:after 伪元素被增加到 .content 容器的每个子元素。

.content {--decorated: true;}

@container style(--decorated: true) {
  :after {
    content: "";
    position: absolute;
    inset: 0;
    background-color: var(--dec-color, green);
    opacity: 0.1;
    z-index: -1;
    transform: rotate(-1.5deg);
  }
}

地址:https://codepen.io/shadeed/pen/abKxgyW/a0e0639a118fac1b781a5d…

RTL 款式:卡片组件

写 RTL 款式时,第一步是在 <html> 元素中增加 dir=rtl。一旦增加,每个元素的 direction CSS 属性都会变为 direction: rtl

随着逻辑属性的衰亡,咱们不须要齐全重写 CSS。思考以下示例:

.item {margin-inline-start: 1rem;}

对于从左到右的布局,上述内容将计算为 margin-left。对于从右到左的布局,它将是 margin-right。很酷,对吧?然而咱们依然没有查看突变方向的逻辑 CSS。

款式查问能够用于解决这个问题。思考以下示例:

咱们有一个组件,由两个元素组成,这两个元素都应依据文档改变方向:

  • 突变:对于 LTR 布局,它从左到右。
  • 箭头方向:指向左边。
  • 上述内容无奈应用逻辑 CSS 管制。目前,咱们这样做:
html[dir="rtl"] .card {background: linear-gradient(to left, ...);
}

html[dir="rtl"] .card__cta {transform: scaleX(-1);
}

应用款式查问,咱们能够查问容器并查看 direction 是否等于 rtl,并依据此对款式进行更改。

.card {
  --bg-angle: to right;
  background: linear-gradient(var(--bg-angle), #5521c3, #5893eb);
}

@container card style(direction: rtl) {
  .card {--bg-angle: to left;}

  .card__cta {transform: scaleX(-1);
  }
}

请留神,款式查问的以后原型不反对 style() 查问中的 CSS 属性。因而,我在示例中应用了 CSS 变量。

新闻模块

这是我在 bbc.com 上发现的实在问题。最后,咱们有以下新闻组件。

依据其容器,款式应略有扭转。思考以下图:

留神组件当初有两个批改:

  • 红色背景。
  • 题目和形容容器周围填充。
  • 这是 BBC.com 上 CSS 的款式:
.media--padded {background: #fff;}

.media--padded .media__content {padding: 0.75rem 0.75rem 3rem 0.75rem;}

咱们如何通过款式查问来解决这个问题呢?很简略,咱们须要一种办法来通知组件,如果你住在这个容器内,卡片的款式应该被填充。

.special-container {--card--padded: true;}

@container style (--card-padded: true) {
  .media {background: #fff;}

  .media__content {padding: 0.75rem 0.75rem 3rem 0.75rem;}
}

总结

CSS 款式查问是 CSS 的弱小补充。我急不可待地想看看社区中的其他人会用它们做什么。哦,我也忍不住想在 iShadeed 实验室中为款式查问创立一个新目录。敬请期待!

原文:https://ishadeed.com/article/css-container-style-queries/

编辑中可能存在的 bug 没法实时晓得,预先为了解决这些 bug, 花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。

交换

有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

退出移动版