当前位置: 首页 > article >正文

CSS 容器查询一探究竟

引言

在 《请列举四种「等比例自适应矩形」实现方案?》 一文中我曾使用到容器查询单位 cqw, 当时在使用 cqw 过程中只是简单过了一下容器查询相关的内容!!

所以这次专门出一篇文章, 对容器查询做一个梳理…

一、是什么

在实际开发中您是否遇到过需要根据父容器的尺寸, 来调整元素的样式呢?

而容器查询, 作用其实就是让我们能够根据父容器的尺寸, 来调整元素的样式!!!

而针对容器查询特性, 出了两个相关功能:

  1. @container: 可根据容器尺寸条件, 来为元素设置不同的样式, 有点类似 @media, 只不过 @media 是根据媒体设备的特征条件, 而 @container 是根据特定容器的尺寸条件来的
  2. 容器查询单位: 可根据最近容器的尺寸为元素设置一个相对的长度单位, 有点类似 vw vh, 唯一的区别是一个相对的是设备的尺寸, 一个是容器尺寸

最后我们来看下它的兼容性: 兼容性还是挺不错的

image

二、定义容器

上文一直提到容器, 那么我们又怎么知道这个容器指的是哪个? @container容器查询单位 又是基于哪个容器做查询的呢?

这里其实可以使用 container-type 来标记某个元素为容器, 这样的话 @container容器查询单位 就知道要作用于哪个元素了

container-type 属性有三个可选值:

属性值说明
normal默认值, 不作为可查询容器使用
inline-size在容器的 内联轴(水平) 方向上, 建立查询容器; (也就是你只能实时获取到容器 内联轴(水平) 方向上的尺寸)
size水平和垂直方向都建立可查询容器 (能够实时获取到容器水平垂直方向上的尺寸)

如下代码, .box 对应元素将被设置为容器:

.box {
  container-type: inline-size;
}

chrome 中, 类似 flex 对于设置为容器的元素, 会有一个 tag 标记

image

三、@container

上文介绍了在 CSS 中是可以通过 container-type 将元素标记为容器, 那么下面我们介绍容器元素结合 @container 来实现响应式布局!!

直接来看个简单 DEMO, 如下代码所示:

  • 通过 container-type.box 设置为容器
  • @container (width < 33em) {} 则将监听页面上容器元素, 当容器宽度小于 33em 将对对应的容器内部元素使用花括号 {} 内的 CSS 规则
<style>
  .box {
    overflow: auto;
    resize: horizontal;
    container-type: inline-size;
  }
  @container (width < 33em) {
    .box p {
      text-align: center;
    }
  }
</style>
<div class="box">
  <p>在实际开发中您是否遇到过需要根据父容器的尺寸, 来调整元素的样式呢?</p>
</div>
<div class="box">
  <p>在实际开发中您是否遇到过需要根据父容器的尺寸, 来调整元素的样式呢?</p>
</div>

最后效果如下: 当我们缩小第一个 .box 宽度时, 当容器小于 33em 那么容器内容文本将居中展示

ScreenFlow

四、多容器

上午其实我们设置了两个容器元素, @container (width < 33em) {} 对这两个容器都会产生作用!!

那么如果我们想要针对每个容器设置不同的 @container 规则, 我们又可以怎么做呢?

其实容器这边还有一个属性 container-name, 通过该属性我们可以为容器设置别名; 同时 @container 也可设置容器名称, 来对指定的容器生效, 如下代码所示:

  • 针对 .first-box.second-box 设置不同的容器别名 container-name
  • @container second (width < 33em) {}: 只对监听 second 容器尺寸, 为其设置响应式布局
<style>
  .first-box,
  .second-box {
    overflow: auto;
    resize: horizontal;
    container-type: inline-size;
  }

  .first-box {
    container-name: first;
  }

  .second-box {
    container-name: second;
  }

  @container second (width < 33em) {
    div p {
      text-align: center;
    }
  }

</style>
<div class="first-box">
  <p>在实际开发中您是否遇到过需要根据父容器的尺寸, 来调整元素的样式呢?</p>
</div>
<div class="second-box">
  <p>在实际开发中您是否遇到过需要根据父容器的尺寸, 来调整元素的样式呢?</p>
</div>

最后效果如下:

  • 缩小 first 容器, 没有任何效果(只是文本正常换行)
  • 缩小 second 容器, 当容器小于 33em@container 生效

ScreenFlow

补充: 上文提到两个容器相关的 CSS 属性: container-typecontainer-name, 它们实际上还有个简写属性 container, 语法: container: <container-name> / <container-type> 例: container: sidebar / inline-size;

五、容器查询单位

既然我们能够实时查询到容器元素的尺寸, 那么自然我们就可以基于容器元素的尺寸来为子元素设置相对长度单位, 也就是所谓的 容器查询单位, 目前已有的容器查询单位有:

单位名备注
cqwContainer Query Width 缩写, 1cqw 等于最近祖先容器宽度的 1%
cqhContainer Query Height 缩写, 1cqh 等于最近祖先容器高度的 1%
cqiContainer Query Inline-Size 缩写, 1cqi 等于最近祖先容器 Inline-Size 方向上对应尺寸的 1%, 默认情况下 Inline-Size 指的就是水平方向, 对应的是宽度
cqbContainer Query Block-Size 缩写, 1cqb 等于最近祖先容器 Block-Size 方向上对应尺寸的 1%, 默认情况下 Block-Size 指的就是垂直方向, 对应的是高度
cqminContainer Query Min 缩写, 1cqmin 等于最近祖先容器最小尺寸的 1%, 例如: 容器宽度为 100 高度为 50, 则会相对于高度(最小的尺寸)进行计算
cqmaxContainer Query Min 缩写, 1cqmax 等于最近祖先容器最大尺寸的 1%, 例如: 容器宽度为 100 高度为 50, 则会相对于宽度(最大的尺寸)进行计算

下面看个简单例子:

  • 通过 container-type 将元素设置为容器
  • p 标签使用 cqw 来设置字体大小 font-size, 让字体大小根据外层容器的宽度进行自适应
  • calc(100cqw / 33): 使用 CSS 函数 calc 来计算长度, 100cqw 等于容器宽度, 33 是文本长度, 那么这样的话就可以保证文本实时占满整个容器
<style>
  .box {
    overflow: auto;
    resize: horizontal;
    container-type: inline-size;
  }

  .box p {
    text-align: center;
    font-size: calc(100cqw / 33);
  }
</style>
<div class="box">
  <p>在实际开发中您是否遇到过需要根据父容器的尺寸, 来调整元素的样式呢?</p>
</div>

最后效果如下: 缩小容器, 文字大小会跟着改变, 文本始终一行展示并占满整个容器

ScreenFlow

六、参考

  • 介绍2022最期待且已正式支持的CSS container容器查询
  • MDN - container
  • MDN - CSS_container_queries
  • MDN - @container

image


http://www.kler.cn/a/350565.html

相关文章:

  • 【汇编器和编译器的区别】
  • Output
  • 新星杯-ESP32智能硬件开发--ESP32的I/O组成-系统中断矩阵
  • 创建 pdf 合同模板
  • ASP .NET Core 学习(.NET9)配置接口访问路由
  • 浅谈计算机网络04 | 现代网络需求与技术支撑
  • Mac实用小技巧之如何输入特殊符号
  • 一文通JavaScript事件处理及高级应用(事件冒泡捕获、冒泡与捕获的区别、事件委托)
  • Web集群服务-Nginx
  • log4j添加druid的慢sql日志记录到指定文件
  • 【IRV2】Deepfake video detection using InceptionResnetV2
  • 安卓的漏洞类型和扫描工具
  • vue3中swiper11的使用
  • Unity-Shader简介
  • 滑动窗口经典例题
  • 【CSS in Depth 2 精译_046】7.1 CSS 响应式设计中的移动端优先设计原则(下)
  • 奖金——Topsort
  • 基于STM32的自学习走迷宫智能小车设计
  • 空间限域效应
  • Java基础14-网络编程
  • 基于springboot学生成绩管理系统
  • linux系统,不定时kernel bug :soft lockup的问题
  • android studio导入外部项目
  • 24/10/12 算法笔记 汇聚层
  • mysqlRouter读写分离
  • 常用分布的数学期望、方差、特征函数