CSS新规范:样式查询

更新日期: 2023-01-02阅读: 678标签: 样式

最近,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/a583817975bae6b78308acb6939a9a54?editors=1100

减少 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[>"true"] {
  counter-reset: list;
}

.most-popular[>"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/b53e0baa891dc48b0689e1f926f89b96?editors=1100

组件级的主题切换

我们构建的一些组件根据特定条件需要使用不同的主题。在下面的示例中,我们有一个包含不同统计组件的仪表板。

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


目前,我们可以使用特殊类根据它们的容器为自定义统计组件添加样式。

.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/464bd92260d290df58e1387c71d1d30f?editors=1100

条件装饰样式

在某些情况下,我们可能需要根据文本元素在 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/a0e0639a118fac1b781a5de18c598789

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/

链接: https://www.fly63.com/article/detial/12286

css样式大全,完整的Css样式大全(整理)

CSS样式被称为为“层叠样式表”,是一种网页制作做不可或缺的技术,是用于装饰网页,达到设计效果的一种样式语言。

css 分割线样式_css实现文章分割线的多种方法总结

这篇文章整理css如何实现文章分割线的多种方式,分割线在页面中可以起到美化作用,那么就来看看使用css实现分割线样式的多种方法:单个标签实现分隔线、巧用背景色实现分隔线、inline-block实现分隔线、浮动实现分隔线、利用字符实现分隔线

原生js获取、添加、修改_非行间css样式

在html中样式分为:浏览器默认样式,引用样式(link外部样式文件,stle标签定义样式)、行间样式(及节点style属性定义的样式)。这篇文章主要讲解使用原生js获取、添加非行间css样式。

css常用样式整理_css属性大全

css常用样式有哪些?这篇文章整理如下内容:字体属性(font)、 常用字体 (font-family)、背景属性 (background)、区块属性 (Block)、方框属性 (Box)、边框属性 (Border)、列表属性 (List-style)、定位属性 (Position)、CSS文字属性

CSS层叠样式表

层叠样式表,用来表现HTML或者XML等文件样式的计算机语言。网页表现与内容分离的样式设计语言,能够对网页中对象排版进行像素级精确控制,几乎支持所有字体字号

如何用自己喜欢的 CSS 风格重置网站的样式

许多前端开发人员都在用 Normalize 为他们的网站设计样式。一些人喜欢在 Normalize.css 中添加一些自己偏好的样式,我也一样。在本文中,我会与你分享我自己的 CSS reset 项目(除了 Normalize.css 之外我还使用它们)。

css单行截断和多行截断问题

多行截断有好几种方法,可以直接使用float方法,方便自定义样式及监听事件,并且兼容性好,是暂时最完美的解决方案。就是略复杂,不过网上有可以直接拿来用哦~

引入CSS样式的三种方式

行内式:该语法中style是标记的属性,实际上任何HTML标记都拥有style属性,用来设置行内式。内嵌式<style>标记一般位于<head>标记中的<title>标记之后,也可以把它放在HTML文档的任何地方。

整理一些少用但又实用的 CSS 样式

什么是偏门,就是有些片段很少使用,时间久了就记不起来,但用的时候又要去找,所以这里为大家整理一些少用但又实用的 CSS 样式,input 的 H5 placeholder 属性,很好用,但不能直接改这个文字颜色

vue用v-html加载渲染,里面的内容样式不生效

需要输出富文本的内容,需要设置里面的图片样式最大宽度100%。可是设置img 100%后没反应,看F12检查元素也没加上去。解决方法有2个:coped属性导致css仅对当前组件生效

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!