前端开发者学堂 - fedev.cn

CSS Grid Layout一些有趣的事情(2)

发布于 大漠

特别声明:此篇文章内容来源于@MANUEL MATUZOVIC的《Another Collection of Interesting Facts About CSS Grid》一文。

去年,我做了一个研讨会之后收集了一些关于CSS Grid布局有趣的东西。今天年,我在另一个工作室工作,我学到了一些更令人兴奋的事情,那就是我们都喜欢布局规范

当然,我不会把这些有趣的东西独享。我很高兴能和大家一起分享这些有趣的东西。

理解grid的快捷方式是如何工作的

有时候,阅读和理解grid规范是非常困难的。例如,我花了很长时间才理解如何正确使用grid快捷方式。该规范声明的有效值有:

<‘grid-template’> | <‘grid-template-rows’> / [ auto-flow && dense? ] <‘grid-auto-columns’>? | [ auto-flow && dense? ] <‘grid-autwo-rows’>? / <‘grid-template-columns’>

如果你花时间或者你有阅读规范的经验,你就能理解它。我尝试了几种组合,但都失败了。最终帮助我的是规范中的一个注释:

注意:你只能在单个网格声明中指定显式或隐式网格属性。

@Rachel Andrew有一系列的文章,使用CSS网格作为一个例子,解释了如何阅读规范。

因此,我们可以使用网格简写来指定大量的东西,但不是所有的都同时使用。这里有一些例子。

使用grid事实上在用grid-template

grid-template属性是grid-template-columnsgrid-template-rowsgrid-template-areas三个属性的简写方式。事实上,我们也可以使用grid的简写来做相同的事情。

grid: "one one" 200px 
    "two four" 
    "three four" 
    / 1fr 2fr;

上面的代码等同于下面的代码:

grid-template-areas: "one one" "two four" "three four";
grid-template-rows: 200px;
grid-template-columns: 1fr 2fr;

这个简写创建了三行两列的一个网格,其中有四个命名的网格区域。第一行的显式高度为200px,而第二行和第三行隐式高度为auto。第一列的宽度为1fr,第二列的宽度为2fr

想知道更多关于显式和隐式网格的区别吗?看看这篇文章

如果不需要,我们不需要指定区域。我们可以使用grid的简写来定义显式的行和列。下面两个代码片段基本上是在做相同的事情:

grid-template-rows: 100px 300px;
grid-template-columns: 3fr 1fr;

/* 等同于 */
grid: 100px 300px / 3fr 1fr;

处理隐式行和列

可以使用grid简写来指定grid-auto-flow,但是它并不像我们预期的那样工作。我们不只是在声明中添加rowcolumn关键词。相反,我们必须在 /的一侧使用auto-flow关键词。

如果auto-flow位于/的左侧,那么grid的简写中grid-auto-flow的值为row和创建显式的列。

grid: auto-flow / 200px 1fr;

/* 等同于 */
grid-auto-flow: row;
grid-template-columns: 200px 1fr;

如果auto-flow位于/的右侧,那么grid的简写中grid-auto-flow的值为column和创建显式的行。

grid: 100px 300px / auto-flow;

/* 等同于 */
grid-template-rows: 100px 300px;
grid-auto-flow: column;

我们还可以将隐式的网格轨道尺寸大小与auto-flow关键词一起使用,auto-flow分别给grid-auto-rowsgrid-auto-columns设置为指定的值。

grid: 100px 300px / auto-flow 200px;

/* 等同于 */
grid-template-rows: 100px 300px;
grid-auto-flow: column;
grid-auto-columns: 200px;

Edge中的查询功能

使用查询功能检查对CSS Grid的支持是非常有用的,因为所有支持grid的浏览器都能理解。这意味着,我们可以检查浏览器是否支持新的或旧的规范,或者两者都支持。你肯定会问,两个都支持?从Edge 16开始,Edge不仅支持新规范,而且还支持旧规范。

所以,如果你想区域是否支持新规范,你可以像下面这样使用查询功能:

/* Edge 16 and higher */
@supports (display: -ms-grid) and (display: grid) {
    div {
        width: auto;
    }
}

/* Edge 15 and lower */
@supports (display: -ms-grid) and (not (display: grid)) {
    div {
        margin: 0
    }
}

这里有一个小示例,它显示了在浏览器中打开的查询特性的触发器。

简单提一下,不要使用浏览器嗅探的特性查询,因为浏览器检测很糟糕

指定每列中项目的确切数

网格对于页面布局来说非常有用,但是它在组件级别上也非常有用。我最喜欢的例子之一是能够在多列组件中指定每列的确切的列表数。

假设我们有一个11项的列表,我们想在每四个项目之后添加一个新的列。首先要做的事情是在它们的父元素上显式的声明display:grid。默认情况之下,它会依次填充每一行,并在必要时添加新的行。如果我们grid-auto-flow设置为column,网格将依次填充每个列,这正是我们想要的。我们要做的最后一件事是指定每个列的列表项数。这可以通过grid-template-rows属性显式定义尽可能多的行来实现。我们可以通过使用auto关键词来显式地设置每一行的高度,或者让它们与内容一样大。

ul {
    display: grid;
    grid-template-rows: auto auto auto auto;

    /* or shorter and easier to read: */
    /* grid-template-rows: repeat(4, auto); */
    grid-auto-flow: column;
}

如果我们必须为每列设置五个列表项,我们只需要在网格轨道后添加新的网格轨道,或者使用repeat()函数,只需要将第一个参数更改为你所需的值,比如:grid-template-rows: repeat(5, auto)

使用CSS Grid实现Sticky footers效果

CSS中创建Sticky Footer效果有很多方法。有一些方法很简单,也有一些方法也很复杂。假设我们有一个类名为headermainfooter的页面结构:

<body>
    <header>HEADER</header>
    <main>MAIN</main>
    <footer>FOOTER</footer>
</body>

如果你重未接触过有关于Sticky Footer相关的知识,建议你点击这里,阅读相关文章

首先把htmlbodyheight设置为100%,以确保页面始终使用完整的垂直空间。然后在body中使用grid-template-rows将其拆分为三行。第一个(header)和最后一个(footer)行可以设置任何我们想要的大小。如果我们想让它们总是和它其内容一样大,我们就把height设置为auto。中间的一行(main)应该总是填满剩余的空间。我们不需要计算高度,因为我们可以使用分子单位来实现。

html {
    height: 100%;
}

body {
    min-height: 100%;
    display: grid;
    grid-template-rows: auto 1fr auto;
}

自动计算最小尺寸的网格项目

最近,@Florian在Twitter上说,他想知道为什么在网格中截断单行文本是如些的复杂。他的例子完美地说明了有关网格项目的一个有趣的事情。

有一个三列的网格,每个网格项目中有一个段落。

<div class="grid">
    <div class="item">
        <p>Lorem ipsum ...</p>
    </div>
</div>

.grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-gap: 20px;
}

每个段落都应该是单行的,如果段落的长度超过其容器宽度时,则在行的末尾显示一个省略号(...)。@Florian通过将white-space设置为nowrap将其强制为一行,然后overflow:hiddentext-overflow:ellipsis来解决这个问题。

p {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

这个方案对于块元素来说是完全可以的,但是在网格示例中,列扩展到单行段的宽度:

从广义上讲,这种情况会发生,因为网格项不能小于它的子元素。一个网格项目(或一个Flex项目)的默认min-width设置示为auto。具体的可以看规范:

...applies an automatic minimum size in the specified axis to grid items whose overflow is visible and which span at least one track whose min track sizing function is auto.

这使用网格和Flex项目更加灵活,但是有时候,内容能够扩展其父容器的宽度是不可取的。为了避免这种情况,我们可以将网格项目的overflow改叫生设置为visible或者将min-width设置为0

有关于这方面更多的信息,可以阅读网格规范中的《Automatic Minimum Size of Grid Items》部分。

总结

希望这些最新的结论能帮助你在写代码和使用网格时能更爽一些。在这个新规范中有很多细节,但是这些细节变得更为有意思,也更容易帮助我们理解CSS Grid。其实今天整理的是属于第二部分了,早前也整理过一些有关于CSS Grid有趣的东西,感兴趣的可以点击这里阅读

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

如需转载,烦请注明出处:https://www.fedev.cn/css/another-collection-of-interesting-facts-about-css-grid.htmlAir Jordan VII 7.5 Ture Flight