Container Query
Size
当组件出现在同一视口大小 (viewport) 页面下的不同地方时,
e.g. .main > .button vs .sidebar > .button,
此时 @media 无法有效实现响应式组件,
使用 @container 可以有效实现响应式组件:
.sidebar {
container-name: sidebar;
container-type: inline-size;
}
@container sidebar (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 2fr 1fr;
}
}
Style
style query direct parent:
@container style(color: hotpink) {
.card {
background: white;
}
}
@container style(font-style: italic) {
span,
i,
.etc {
background: lavender;
}
}
@container style(border-color: lightblue) {
button {
border-color: royalblue;
}
}
@container style(--theme: dark) {
.card {
color: white;
background: royalblue;
border-color: navy;
}
.card button {
color: white;
background-color: dodgerblue;
border-color: navy;
}
}
/* Update the theme on hover */
.card:hover,
.card:focus {
--theme: dark-hover;
}
/* Apply darkHover theme styles */
@container style(--theme: dark-hover) {
.card {
background: dodgerblue;
border-color: navy;
}
.card button {
background-color: royalblue;
border-color: lightblue;
}
}
@container (min-width: 420px) and style(--highlight: true) {
/* Styles for only highlight components at a minimum width of 420px */
.title {
color: var(--highlight-color);
}
}
Non-direct parent:
<ul class="card-list">
<li class="card-container">
<div class="card"></div>
</li>
</ul>
<style>
.card-list {
container-name: cards;
}
@container cards style(--theme: warm) {
.card {
background-color: wheat;
}
}
</style>
Use style query to
implement toggle() function:
:is(i, em, blockquote, code) {
font-style: var(--font-style);
--font-style: italic;
@container style(--font-style: italic) {
--font-style: normal;
}
}
Scroll
scroll-state
query:
.parent {
container-type: scroll-state;
}
.child {
/* styles */
@container scroll-state(<type>: <value>) {
/* scroll-based styles */
}
}
Stuck
停滞 (边缘固定) 时:
.stuck-top {
position: sticky;
top: 0;
container-type: scroll-state;
@supports (container-type: scroll-state) {
> nav {
@container scroll-state(stuck: top) {
color: var(--color-highlight-foreground);
background: var(--color-highlight);
}
}
}
}
Snapped
已贴靠 (轴上对齐) 时:
.hidden-not-snapped {
overflow: auto hidden;
scroll-snap-type: x mandatory;
> article {
container-type: scroll-state;
scroll-snap-align: center;
@supports (container-type: scroll-state) {
> * {
transition: opacity 0.5s ease;
@container not scroll-state(snapped: x) {
opacity: 0.25;
}
}
}
}
}
Scrollable
可滚动 (内容溢出) 时:
.scroll-container {
container-type: scroll-state size;
overflow: auto;
&::after {
content: ' ';
background: var(--shadow-top), var(--shadow-bottom);
transition:
--scroll-shadow-color-1-opacity 0.5s ease,
--scroll-shadow-color-2-opacity 0.5s ease;
@container scroll-state(scrollable: top) {
--scroll-shadow-color-1-opacity: var(--shadow-color-opacity, 25%);
}
@container scroll-state(scrollable: bottom) {
--scroll-shadow-color-2-opacity: var(--shadow-color-opacity, 25%);
}
}
}
Scrolled
已滚动时:
html {
container-type: scroll-state;
}
header {
@container (not scroll-state(scrolled: none)) {
position: sticky;
top: 0;
transition: translate 0.2s;
}
/* Hide when scroll down */
@container scroll-state(scrolled: bottom) {
translate: 0 -100%;
}
/* Appear when scroll up */
@container scroll-state(scrolled: top) {
translate: 0 0;
}
}
References
- Interactive and comprehensive CSS container queries guide.