又是在网上流浪的一天 …
今天学习css的一个新特性:@container
容器查询,其实也不是很新了。(2022年各大浏览器开始支持)
提到查询,大家是不是首先会想到 @media
,
媒体查询 @media
在目前前端响应式方案中,最常见的就是通过@media
来实现,比如根据可视窗口的宽高动态改变元素的尺寸或内容。
@media
的使用规则为:
COPY
1 | @media 媒体类型 媒体特征表达式{ |
如下,在screen
最大宽度为600px
跟900px
时,div的背景色也响应式的发生了变化。这里只是简单举个例子,更多使用特性可以在MDN上查看
COPY
1 | @media screen and (max-width: 600px) { |
那当我们想对div
的子元素也进行响应式处理呢?
COPY
1 | @media screen and (max-width: 600px) { |
可以看到某些场景下,子元素如果也要根据条件进行响应式,则需要继承父元素的条件,多少有点繁琐了。
那么我们是否可以使用 @container
实现呢?
上述例子可以在codepen上查看
容器查询 @container
不同于@media
针对于各重媒体类型的查询,@container
针对的是对容器内部元素进行处理。
@media
适用于外层,@container
适用于内层,@container
颗粒度更细
基本使用
@container
的使用规则为:
COPY
1 | @container 容器条件{ |
比如:
COPY
1 | @container (width > 400px) { |
关键字
可以使用以下关键字:
and
与条件(同时满足)or
或条件(满足其一即可)not
否定条件(取反)
注意:and每个容器查询只允许有一个“not”条件,并且不能与or
关键字一起使用
COPY
1 | /* 容器宽度大于等于400时生效*/ |
具体效果见:https://codepen.io/guozhigq/pen/oNQZQVj
在上面的例子中,可能有同学发现我们对于父元素添加了container-type: size
属性,那么这个属性又起什么作用呢?
关键属性
container-type
属性定义在父元素中,用来指定查询的范围(条件)
主要有以下的值:
- size
- 监听父元素的 宽、高 变化。定义为
size
后,可以使用width
、height
的判断条件。
可以尝试将例子中的container-type: size
改为container-type: inline-size
尝试,你会发现与height
相关的判断会失效(inline-size
监听父元素的 宽 的变化)COPY1
2
3
4
5
6
7
8
9
10
11
12
13
14.card{
/* container-type: size; */
container-type: inline-size;
}
/* 判断条件中没有 height,仍然有效 */
@container not (width < 400px){}
/* 判断条件中有 height,失效 */
@container (width > 400px) and (height > 400px){}
/* 判断条件中 height 不是唯一条件,仍然有效 */
@container (width > 400px) or (height > 400px){}
/* @container (width > 400px) not (height > 400px){} */
- 监听父元素的 宽、高 变化。定义为
- inline-size
- 监听父元素的 宽 变化,在此条件下与
height
相关的判断不生效,参考以上代码
- 监听父元素的 宽 变化,在此条件下与
- normal
- 不监听父元素的尺寸变化,在此条件下
width
、height
的判断条件都不生效,
- 不监听父元素的尺寸变化,在此条件下
判断条件
另外的,判断条件除了width
、height
之外还有:
- aspect-ratio: 根据父元素的比例进行判断 COPY
1
2
3
4
5
6
7
8.card{
/* container-type 必须设置为size */
container-type: size;
}
/* 判断宽高比大于2时生效 */
@container (aspect-ratio > 2){}
/* 结合其他判断条件一起使用 */
@container (aspect-ratio > 2) and (width > 400px) and (height > 400px){} - orientation: 根据屏幕方向进行判断(landscape横屏 portrait竖屏)
- 在codepen测试时,父元素 width > height时landscape(横屏)生效
- 在codepen测试时,父元素 width < height时portrait(竖屏)生效COPY
1
2
3
4
5
6
7
8
9.card{
/* container-type 必须设置为size */
container-type: size;
}
/* 在codepen测试时,父元素 width > height时landscape生效 */
/* 在codepen测试时,父元素 width <> height时portrait生效 */
@container (orientation: landscape){}
@container (orientation: portrait){}
- inline-size: 具体如何使用暂时不清楚
- block-size: 具体如何使用暂时不清楚
综上,可以看出来@container
的判断基于父元素,而@media
则基于视图,@container
使用更灵活,能够满足更多的使用场景。