51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

CSS基础介绍:CSS 容器查询简介

容器查询启用基于可用空间的元素样式。它们使我们能够构建可适应无限、未知布局安排的弹性组件。这与视口媒体查询形成对比,视口媒体查询需要在页面级别协调样式更改。


容器查询与视口媒体查询 {#container-queries-vs-viewport-media-queries}

我们很可能熟悉响应视口的响应式设计和布局,如下图所示。

image.png


在视口响应式设计中,将布局网格耦合到断点很流行。这些断点通常与简化的设备尺寸有关,如上图所示,例如手机、平板电脑和台式机。

重要的是,这些断点不一定考虑屏幕上的单个元素和组件,更侧重于组件如何流入预定义的网格。有时,较大的组件(如导航)会与网格分开变形,但通常它们会使用全局断点。

让我们将视口响应式设计与容器响应式设计进行对比。

下图是卡片组件的变体。这三种变体是使用完全独立于视口的容器查询呈现的。卡片样式根据可用空间进行调整。

image.png


注意:自 Firefox 110 发布以来,所有常青浏览器都支持容器查询。为了扩展对旧浏览器的支持,可以使用 polyfill

首先,让我们学习创建容器查询的语法。

定义容器查询 {#defining-container-queries}

第一步是使用属性指定元素是容器container-type。最基本且目前支持最好的值是inline-size,在水平书写模式下它等于元素的宽度。所以这个定义意味着我们打算支持基于.container元素的行内大小的查询:

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

向元素添加 acontainer-type正式将其指定为容器。

接下来,我们将使用容器 at 规则创建实际的容器查询,如果我们曾经分配过媒体查询,它会接受一个看起来很熟悉的参数。

下面的@container规则说,当 an<h2>在一个40ch宽或更大的容器内时,它的颜色应该是蓝色:

@container (min-width: 40ch) {
  h2 {
    color: blue;
  }
}

注意:我们放置在容器查询中的规则不会影响容器本身的样式,只会影响其子项。这意味着我们无法从容器自身的查询中设置容器的样式。但是,如果容器的祖先也被定义为容器,我们可以使用容器查询来设置容器的样式。

为了适应不仅仅是水平书写模式,我们可以更新我们的查询以使用 的逻辑语法inline-size,而不是严格基于容器的"宽度"查询:

@container (inline-size > 40ch) {
  h2 {
    color: blue;
  }
}

还有更多选项inline-size,包括block-sizeaspect-ratio。要了解有关可用大小容器查询以及如何使用它们的更多信息,请查看官方规范


升级卡片组件 {#upgrading-a-card-component}

如果我们想构建一个没有容器查询的卡片组件,我们可以通过修饰类创建变体。对于卡片大小的变化,这些修饰符可以与断点相关联。这意味着,如果卡片有修饰符,则当视口宽度落在该断点内时,它会被允许更改。

下图显示了三种卡片大小变化及其各自的修改器类别,其中顶部.card将被视为"默认"。

image.png

现在让我们换个角度思考如何使用容器查询来处理这些卡片变体。

我们仍会将顶部卡片设为默认卡片,这实际上意味着它将应用于最窄的宽度。这也将是不支持容器查询的回退版本------在容器查询达到支持成熟度之前需要考虑的一个重要场景。

我们将为中型卡片(水平方向)设置布局,以便在容器宽度为350px或更大时激活。

最后,当容器的宽度为600px或更大时,我们将卡片布局设置为使用其图像作为背景。

image.png

这将创建一个可根据卡片容器的大小进行调整的卡片元素。试玩以下CodePen 演示以了解实际效果。(请注意右下角的"调整我的大小!"手柄。)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .card {
  --img-ratio: 2/1;

  display: grid;
  gap: 1rem;
  padding: 1rem;
  box-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.35);
  border-radius: 0.5rem;
}

.card > img {
  height: max(18vh, 12rem);
  object-fit: cover;
  width: 100%;
}

@supports (aspect-ratio: 1) {
  .card > img {
    aspect-ratio: var(--img-ratio);
    height: auto;
  }
}

.card__content > :not(h2, h3, h4) {
  font-size: 0.9rem;
}

.card__content {
  display: grid;
  gap: 0.5rem;
  gap: 1cqb;
}

.card-list {
  align-items: start;
}

.card-list li {
  container-type: inline-size;
}

@container (min-width: 350px) {
  .card {
    --img-ratio: 1;
    grid-auto-flow: column;
    align-items: center;
  }
}

@container (min-width: 600px) {
  .card {
    --img-ratio: 2/1;
    grid-template-areas: "card";
    place-items: center;
    padding: 0;
    overflow: hidden;
  }

  .card > * {
    grid-area: card;
  }

  .card__content {
    text-align: center;
    color: #fff;
    padding: 1rem;
  }

  .card__content {
    font-size: 2rem;
  }
}

    </style>
</head>
<body>
    <aside role="note">
        <p>Your browser doesn't natively support container queries, but the demo works thanks to the polyfill! Refer to the JS tab for how to include it.</p>
      </aside>
     
      <ul role="list" class="flexbox-grid card-list container resize">
        <li>
          <div class="card">
            <img src="https://assets.codepen.io/1101822/jellyfish.jpg" alt="Pink and purple small flourescent jellyfish with white spotted caps float in inky darkness." width="400" height="300">
            <div class="card__content">
              <h3>Dolor sit amet</h3>
              <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
            </div>
          </div>
        </li>
        <li>
          <div class="card">
            <img src="https://assets.codepen.io/1101822/jellyfish.jpg" alt="Pink and purple small flourescent jellyfish with white spotted caps float in inky darkness." width="400" height="300">
            <div class="card__content">
              <h3>Dolor sit amet</h3>
              <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
            </div>
          </div>
        </li>
        <li>
          <div class="card">
            <img src="https://assets.codepen.io/1101822/jellyfish.jpg" alt="Pink and purple small flourescent jellyfish with white spotted caps float in inky darkness." width="400" height="300">
            <div class="card__content">
              <h3>Dolor sit amet</h3>
              <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
            </div>
          </div>
        </li>
      </ul>

      <script>
        // Support Test
        const supportsContainerQueries = "container" in document.documentElement.style;

        // Conditional Import
        if (!supportsContainerQueries) {
        import("https://cdn.skypack.dev/container-query-polyfill");
        }

      </script>
</body>
</html>

赞(0)
未经允许不得转载:工具盒子 » CSS基础介绍:CSS 容器查询简介