本文首发于微信公众号:大迁世界, 我的微信: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 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。