51工具盒子

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

没有媒体查询的响应式 CSS 布局网格

500.jpg

现在我们做的响应式布局的一般都会用到媒体查询工具,那么能不能不用呢?那我告诉您,可以的,不妨来一试吧。

带有网格的响应式布局

首先可能是我最喜欢的所有解决方案,因为它的多功能性和易用性。使用 Grid,我们可以创建一组响应式列,这些列可以根据需要自行创建。我们将提供一个单一的约束------列的最小宽度------它在列项目进入新行之前作为一种"断点"发挥双重作用。

这是完成此响应式网格布局所需的全部,其中我们的最小列大小是30ch通过辅助自定义属性设置的。此规则指示浏览器创建尽可能多的列,这些列至少要30ch宽:

.grid {
  --min: 30ch;

  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--min)), 1fr));
}

由于1fr是 的"最大"值minmax(),因此还允许列拉伸以公平地填充行内的任何剩余空间。因此,如果可用空间为80ch并且有两个网格子项,它们将各自占用40ch. 如果有三个孩子,第三个将在第二行,因为80没有平均分配到允许的最小大小30

以下提供了响应式网格布局的实时示例:

<!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>带有网格的响应式布局 | Web前端之家www.jiangweishan.com</title>
    <style>
        
        html {
        height: 100%;
        }

        body {
        font-family: system-ui;
        min-height: 100%;
        background-color: var(--bg, mediumvioletred);
        padding: var(--padding, 0);
        max-width: var(--max-width, 120ch);
        margin-inline: auto;        
        --padding: 5vw;
        --max-width: 180ch;
        }
        ul,li {
            display: list-item;
            text-align: -webkit-match-parent;
        }
        * {
        box-sizing: border-box;
        margin: 0;
        }
        .grid {
        --min: 30ch;

        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--min)), 1fr));

        gap: 1rem;
        }        

        :where([role="list"]) {
        margin: 0;
        padding: 0;
        list-style: none;
        }

        .card {
        padding: clamp(0.75rem, 5%, 3rem);
        background-color: #fff;
        border-radius: 1rem;
        }

    </style>
</head>
<body>
    <ul role="list" class="grid">
        <li class="card">
          <h3>Lorem, ipsum.</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
        </li>
        <li class="card">
          <h3>Minus, pariatur?</h3>
          <p>Veritatis optio illum possimus eveniet exercitationem perferendis ad?</p>
        </li>
        <li class="card">
          <h3>Iste, assumenda!</h3>
          <p>Esse minima in maiores similique unde eaque nostrum!</p>
        </li>
        <li class="card">
          <h3>Voluptatem, veritatis!</h3>
          <p>Provident deserunt veniam, debitis alias atque deleniti laboriosam!</p>
        </li>
        <li class="card">
          <h3>Accusamus, magnam.</h3>
          <p>Ipsum accusantium laboriosam, architecto cum dolor odit animi?</p>
        </li>
        <li class="card">
          <h3>Recusandae, placeat.</h3>
          <p>Incidunt, aliquid odit! Eaque nihil mollitia repellat beatae.</p>
        </li>
    </ul>
</body>
</html>

使用 Flexbox 的响应式布局

我们可以用 Flexbox 完成类似的体验。Flexbox 和 Grid 解决方案之间的区别在于,流向新行的网格项不能扩展到多个网格列。使用 Flexbox,我们可以引导 flex 项目增长以填充所有剩余的额外空间,从而防止在 Grid 解决方案中出现"孤儿"。

在此代码中,与在 Grid 代码中一样,浏览器将创建尽可能多的列,以适应行内空间,大小至少--min30ch. 如果我们有三个项目,第三个需要移动到一个新行,由于简写,它会占用剩余的空间flex,重要的是设置flex-grow1. 因此,它在大多数情况下具有类似的行为1fr

.flexbox-grid {
  --min: 30ch;

  display: flex;
  flex-wrap: wrap;
}

.flexbox-grid > * {
  flex: 1 1 var(--min);
}

由于该属性,下图显示了跨越两列的最终奇数列表项flex-grow

image.png


注意:在 Grid 和 Flexbox 解决方案中,如果我们添加一个gap,那么在添加新行之前可以创建多少列的计算中会减去该空间。

敏锐的读者可能已经注意到这些解决方案之间的另一个关键区别:使用 Grid 时,父级定义子级行为。对于 Flexbox,我们在子项上设置子布局行为。简写flex顺序依次为flex-growflex-shrinkflex-basis

作为实验,我们可以将flex-grow值更改为0,看看项目如何只扩展到该flex-basis值。flex-shrink(用下面的 CodePen 演示进行实验。)保持很重要1,这样,最终------当可用内联空间比 窄时flex-basis------仍然允许项目"收缩",因为这有助于防止溢出。

下面的展示了我们的 Flexbox 布局。

<!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>带有网格的响应式布局 | Web前端之家www.jiangweishan.com</title>
    <style>
        * {
  box-sizing: border-box;
  margin: 0;
}

html {
  height: 100%;
}

body {
  font-family: system-ui;
  min-height: 100%;
  background-color: var(--bg, mediumvioletred);
  padding: var(--padding, 0);
  max-width: var(--max-width, 120ch);
  margin-inline: auto;
}

:where([role="list"]) {
  margin: 0;
  padding: 0;
  list-style: none;
}

.card {
  padding: clamp(0.75rem, 5%, 3rem);
  background-color: #fff;
  border-radius: 1rem;
}
        
        .flexbox-grid {
        --min: 30ch;

        display: flex;
        flex-wrap: wrap;

        gap: 1rem;
        }

        .flexbox-grid > * {
        flex: 1 1 var(--min);
        }

        body {
        --padding: 5vw;
        --max-width: 180ch;
        }

    </style>
</head>
<body>
    <ul role="list" class="flexbox-grid">
        <li class="card">
          <h3>Lorem, ipsum.</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
        </li>
        <li class="card">
          <h3>Minus, pariatur?</h3>
          <p>Veritatis optio illum possimus eveniet exercitationem perferendis ad?</p>
        </li>
        <li class="card">
          <h3>Iste, assumenda!</h3>
          <p>Esse minima in maiores similique unde eaque nostrum!</p>
        </li>
      </ul>
</body>
</html>

flex-basis可以针对此解决方案进一步调整该属性,以便为不同的项目分配唯一的"断点"。由于我们通过--min自定义属性设置该值,并且 Flexbox 子元素控制自己的大小,因此我们可以使用内联样式对其进行调整:

<li style="--min: 40ch">...</li>

此示例中的其他列表子项仍将围绕它流动并使用30ch来自基本规则,但更宽的列有效地改变了行为。

这是此代码的演示:

<!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>带有网格的响应式布局 | Web前端之家www.jiangweishan.com</title>
    <style>
        * {
  box-sizing: border-box;
  margin: 0;
}

html {
  height: 100%;
}

body {
  font-family: system-ui;
  min-height: 100%;
  background-color: var(--bg, mediumvioletred);
  padding: var(--padding, 0);
  max-width: var(--max-width, 120ch);
  margin-inline: auto;
}

:where([role="list"]) {
  margin: 0;
  padding: 0;
  list-style: none;
}

.card {
  padding: clamp(0.75rem, 5%, 3rem);
  background-color: #fff;
  border-radius: 1rem;
}

        
.flexbox-grid {
  --min: 25ch;

  display: flex;
  flex-wrap: wrap;

  gap: 1rem;
}

.flexbox-grid > * {
  flex: 1 1 var(--min);
}

body {
  --padding: 3vw;
  --max-width: 180ch;
}


    </style>
</head>
<body>
    <ul role="list" class="flexbox-grid">
        <li class="card">
          <h3>Lorem, ipsum.</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
        </li>
        <li class="card" style="--min: 40ch">
          <h3>Custom "Breakpoint" --min</h3>
          <p>Veritatis optio illum possimus eveniet exercitationem perferendis ad?</p>
        </li>
        <li class="card">
          <h3>Iste, assumenda!</h3>
          <p>Esse minima in maiores similique unde eaque nostrum!</p>
        </li>
        <li class="card">
          <h3>Molestiae, quo.</h3>
          <p>Quos ullam, iure inventore delectus sequi aliquam omnis!</p>
        </li>
        <li class="card">
          <h3>Illo, facere!</h3>
          <p>Vel pariatur quod alias, quaerat porro sint quas.</p>
        </li>
      </ul>
</body>
</html>

以下是另外两种以有趣的方式使用flex-grow和 的Flexbox 技术flex-basis

  • Heydon Pickering 的Flexbox Holy Albatross,它根据父容器的总宽度从列分解为一行。

  • Heydon Pickering 和 Andy Bell 的侧边栏布局,它展示了如何强制使用不同的基于 Flexbox 的断点以更好地控制项目何时换行。


赞(0)
未经允许不得转载:工具盒子 » 没有媒体查询的响应式 CSS 布局网格