随着 web 应用程序变得越来越复杂, 我们需要一种更自然的方式来轻松地进行高级布局, 而不需要使用浮动和其他负担更少的技术的黑客解决方案. CSS Grid 布局模块 https://drafts.csswg.org/css-grid/ 提供了一个令人兴奋的新布局解决方案.
在这个介绍性教程中, 介绍这个相对较新的 CSS 特性, 讨论当前的浏览器支持, 并使用一些示例展示 CSS 网格布局模块是如何工作的.
什么是 CSS Grid 布局模块?
Grid 布局背后的核心思想是将 Web 页面划分为列和行, 以及根据我们根据大小, 位置和层创建的行和列来定位和调整构建块元素的位置和大小.
Grid 还为我们提供了一种灵活的方法, 只使用 CSS 就可以更改元素的位置, 而不需要更改 html. 这可以与媒体查询一起使用, 在不同的断点处更改布局.
浏览器支持
在我们深入了解网格布局之前, 重要的是要了解浏览器支持的状态 http://caniuse.com/#feat=css-grid .
现代浏览器中的支持
从上图中可以看到, 最新版本的大多数浏览器都支持 CSS Grid.
如果单击 "Can I use" 上的 "Show all" 选项, 将看到此支持的后退距离. 因为 Grid 是一个新特性, 因此向后兼容性不会太长, 所以如果您的受众有可能使用较旧版本的主浏览器, 则需要牢记这一点.
Internet Explorer ... 和其他不支持的浏览器
Grid Layout 的第一个提议是由 Microsoft 开发的, IE10 附带了一个 - ms 前缀的实现. 如果你看一下我能用的支持 http://caniuse.com/#feat=css-grid , 你会发现 IE10 和 IE11 都支持 CSS Grid...... 但要注意的是, 它们只支持规范的旧版本. 这不会改变的. 但是会改变的是这些浏览器的用法. 2018 年 7 月, 全球 IE11 使用率降至 2% 左右, IE10 使用率约为 10%.
我也可以使用其他一些浏览器不支持 Grid Layout. 其中包括 Opera Mini 和 BlackBerry 浏览器. Opera Mini 是唯一一款使用率很高的浏览器, 但由于它是一款移动浏览器, 因此您很可能希望以移动友好的非 Grid Layout 作为目标.
不支持浏览器的回退
鉴于目前使用的绝大多数浏览器都支持 CSS Grid, 在某些浏览器可能不支持它的基础上使用它是一种耻辱. 使用 Grid 有各种选项, 并为不支持的浏览器提供完全足够的回退.
也许最简单的选择是提供简单的 "移动优先" 布局. 这对于不支持网格的移动设备以及 IE 等桌面浏览器来说非常合适.
另一种选择是使用更复杂的回退和覆盖来产生与网格类似的结果, 如 Rachel Andrew 所概述的那样.
https://github.com/FremyCompany/css-grid-polyfill 还可以为不支持网格模块的浏览器提供网格模块的工作实现. 注意, 这可能有点过时了.
网格布局示例
让我们从一个示例开始, 看看 Grid Layout 的强大功能, 然后我将更详细地解释一些新概念.
想象一下, 创建一个具有四个全高列布局 (推文, 回复, 搜索和消息) 的 Twitter 应用程序, 抽象的内容与下面的屏幕截图类似.
这是我们的 HTML:
- <div class="app-layout">
- <div class="tweets">Tweets</div>
- <div class="replies">Replies</div>
- <div class="search">Search</div>
- <div class="messages">Messages</div></div>
然后我们将一些 CSS 应用于. App-layout 容器元素:
- .App-layout {
- display: grid; /* 1 */
- grid-template-columns: 1fr 1fr 1fr 1fr; /* 2 */
- grid-template-rows: 100vh; /* 3 */
- }
在这里查看演示 http://codepen.io/SitePoint/pen/ONPGqz
以下是我们在之前的 CSS 中所做的解释:
将 display 属性设置为 grid.
将容器元素分成四列, 每列是网格容器中可用空间的 1fr (一小部分) https://drafts.csswg.org/css-grid/#fr-unit .
创建一行并将高度设置为 100vh(全视口高度).
如您所见, Grid 布局模块向 display 属性添加了一个新值, 即 grid.grid 值负责将. App-layout 元素设置为一个网格容器, 该容器还为其内容建立一个新的网格格式化上下文. 开始使用网格布局时需要此属性.
该 grid-template-columns 属性指定 Grid 中每个网格列的宽度, 在我们的示例中, 它将. App-layout 容器划分为四列; 每个是 1fr 可用空间的(25%).
在 grid-template-rows 指定每个网格行的高度, 并在我们的例子中, 我们只在创建一行 100vh.
具有两列和两行的布局如下所示:
我们将使用以下 CSS:
- .App-layout {
- display: grid;
- grid-template-columns: 1fr 1fr;
- grid-template-rows: 50vh 50vh;
- }
在这里查看演示 http://codepen.io/SitePoint/pen/grbJav
我们还可以通过将代码包装在媒体查询中, 仅在小屏幕上实现上述示例. 这为我们提供了一个很好的机会, 可以在不同的视口中以不同的方式自定义布局. 例如, 我们只能在视口下创建以前的布局 1024px, 如下所示:
- @media screen and (max-width: 1024px) {
- .App-layout {
- display: grid;
- grid-template-columns: 1fr 1fr;
- grid-template-rows: 50vh 50vh;
- }
- }
在这里查看演示 http://codepen.io/SitePoint/pen/aNzrdd
CSS Grid 布局模块
现在您已经看到了一个简单的示例, 我想介绍一些新概念, 以便您更好地理解 Grid Layout. 虽然有很多新概念, 但我只会看看其中的一些概念.
Grid Item
Grid Item 是网格容器的子元素. 在上面的示例中. tweets, 和. replies 元素将符合网格项.
Grid Lines
Grid Lines 是存在于列或行的任一侧的线. 有两组网格线: 一组定义列(垂直轴), 另一组定义行(水平轴).
从上面的屏幕截图 (代表第一个示例) 开始, 我在 1fr 每个屏幕上创建了四列, 这将为我们提供五条垂直线. 我还创建了一行, 它给了我们两条水平线.
让我们看看我们如何在网格容器中定位网格项.
使用行号定位项
可以使用属性 grid-column-start 和 grid-column-end 引用网格中的准确行号. 然后, 我们将这些属性赋予起始行号和结束行号.
看看前面的例子, 这是浏览器在默认情况下为我们定位元素的方式:
- .tweets {
- grid-column-start: 1;
- grid-column-end: 2;
- grid-row: 1;
- }
- .replies {
- grid-column-start: 2;
- grid-column-end: 3;
- grid-row: 1;
- }
- .search {
- grid-column-start: 3;
- grid-column-end: 4;
- grid-row: 1;
- }
- .messages {
- grid-column-start: 4;
- grid-column-end: 5;
- grid-row: 1;
- }
查看. tweet 列的代码, 这是 CSS 中的三行代码中的每一行:
从左侧第一条垂直线开始定位子元素.
结束元素在第二条垂直线的位置.
将元素放在整行中.
您可以通过改变不同位置元素的顺序改变这一点, 所以元素的顺序将是:.search,.replies,.messages, 和. tweets.
我们可以这样做:
- .tweets {
- grid-column-start: 4;
- grid-column-end: 5;
- grid-row: 1;
- }
- .replies {
- grid-column-start: 2;
- grid-column-end: 3;
- grid-row: 1;
- }
- .search {
- grid-column-start: 1;
- grid-column-end: 2;
- grid-row: 1;
- }
- .messages {
- grid-column-start: 3;
- grid-column-end: 4;
- grid-row: 1;
- }
我们还可以使用 grid-column 简写属性在一行中设置起始行和结束行:
- .tweets {
- grid-column: 4 / 5;
- grid-row: 1;
- }
- .replies {
- grid-column: 2 / 3;
- grid-row: 1;
- }
- .search {
- grid-column: 1 / 2;
- grid-row: 1;
- }
- .messages {
- grid-column: 3 / 4;
- grid-row: 1;
- }
在这里查看演示 http://codepen.io/SitePoint/pen/BKyeKV
这已经改变了仅使用 CSS 的布局结构, 而标记仍然没有任何变化. 这是使用网格布局模块的巨大优势. 我们可以独立于源顺序重新排列元素的布局, 因此我们可以针对不同的屏幕尺寸和方向实现任何所需的布局.
使用命名区域定位项目
网格区域是用于布置一个或多个网格项的逻辑空间. 我们可以使用 grid-template-areas 属性显式命名网格区域, 然后我们可以使用属性将网格项目放入特定区域 grid-area.
为了使这个概念更加清晰, 让我们重新 search 放置第一列的四列示例:
- .App-layout {
- display: grid;
- grid-template-columns: 1fr 1fr 1fr 1fr;
- grid-template-rows: 100vh;
- grid-template-areas: "search replies messages tweets";
- }
在最后一行中, 我们将网格容器划分为四个命名网格区域, 每个名称用于一列. 下一步是将每个网格项定位到命名区域:
- .search {
- grid-area: search;
- }
- .replies {
- grid-area: replies;
- }
- .messages {
- grid-area: messages;
- }
- .tweets {
- grid-area: tweets;
- }
在这里查看演示 http://codepen.io/SitePoint/pen/LNEoZx
Slack Example
如何使用网格布局模块来实现更复杂的示例, 例如, 创建 Slack 布局的构建块. 由于我们讨论布局, 我们将抽象并简化 Slack 设计到网格中表示的构建块. 像这样的东西:
从这个布局我们将创建三个垂直列和三个水平行, 我们可以使用网格线将其可视化, 如下所示:
这是 HTML:
- <div class="app-layout">
- <div class="teams">Teams</div>
- <div class="channels">Channels</div>
- <div class="header">Header</div>
- <div class="messages">
- <ul class="message-list">
- <li></li>
- <li></li>
- </ul>
- </div>
- <div class="input">
- <input type="text" placeholder="CSS Grid Layout Module">
- </div>
- </div>
而 CSS:
- .App-layout {
- display: grid;
- height: 100vh;
- grid-template-columns: 100px 250px 1fr;
- grid-template-rows: auto 1fr auto;
- }
在这里, 我使用 grid-template-columns 属性以 100px,250px 创建三列, 第三列占用剩余的可用空间. 最后一行创建三行: 第一行和第三行具有自动高度, 而中间行占用剩余的可用空间.
CSS 的其余部分如下所示:
- .teams {
- grid-column: 1;
- grid-row: 1 / 4;
- }
- .channels {
- grid-column: 2;
- grid-row: 1 / 4;
- }
- .header {
- grid-column: 3;
- grid-row: 1;
- }
- .messages {
- grid-column: 3;
- grid-row: 2;
- }
- .input {
- grid-column: 3;
- grid-row: 3;
- }
在这里查看演示 http://codepen.io/SitePoint/pen/MyYdeN
我们还可以使用命名区域创建 Slack 布局, 您可以在此演示 http://codepen.io/SitePoint/pen/BKyeLP 中看到.
Grid 布局模块与 Flexbox
由于你们很多人已经开始使用 Flexbox, 你可能会想: 什么时候使用 Flexbox 是合适的, 什么时候使用 Grid 布局更合适?
我从 Tab Atkins 那里找到了一个很好的解释:
Flexbox 适用于许多布局和许多 "页面组件" 元素, 因为它们中的大多数基本上是线性的. 网格适用于整体页面布局, 以及适用于设计中不是线性的复杂页面组件.
这两个可以任意组合, 所以一旦它们得到广泛支持, 我相信大多数页面将由整体布局的外部网格, 嵌套的 flexbox 和页面组件的网格组合, 最后阻止 / 页面 "叶子" 处的内联 / 表格布局, 文本和内容的实时位置
此外, 雷切尔安德鲁说:
行和列的主页结构的网格布局.
Flexbox 用于导航, UI 元素, 您可以线性化的任何内容.
CSS 网格布局模块资源
我没有涵盖所有网格布局概念和语法, 因此我建议您查看以下资源以进一步深入:
CSS Grid 布局模块规范 https://drafts.csswg.org/css-grid/
CSS Grid 布局示例
Grid 示例 http://gridbyexample.com/
CSS 布局的未来: Grid 布局
关注 Rachel Andrew https://rachelandrew.co.uk/ 获取更新和资源. 她在网格布局方面做了很多很棒的工作.
结论
正如您所见, CSS Grid 布局模块功能强大, 因为它的代码简洁, 并且您可以在不触及标记的情况下更改布局顺序. 这些功能帮助我们永久地改变了为 Web 创建布局的方式.
来源: http://www.css88.com/web/css/11818.html