放弃 CSS 框架,转而使用 Grid 和 Flexbox
我从 2000 年到 2010 年就开始接触 CSS,那时到处都是各种 CSS hack。我习惯了用浮动、行内阻塞和 clearfix 来管理布局。几年前我尝试学习过 Flexbox,但那时它刚推出,大多数属性都带有浏览器前缀,而且并不总是有效。所以我就放弃了,暂时搁置了前端开发,等待它成熟。
我通过订阅使用Bootstrap、Foundation和Skeleton等框架的培训课程来避免痛苦。这些课程就像避风港,让我可以快速构建应用程序并专注于提供可靠的后端。
当我走到同事身边问他正在做什么时,我的兴趣再次被激发了出来。他给我看了两个关于 CSS网格和弹性布局的教程,并快速演示了它们结合使用的效果,我简直惊呆了。
我决定不使用 CSS 框架,仅使用 Grid 和 Flexbox 来构建一个页面。不得不说,我非常满意这种方式,它简单直接,让我能够轻松创建一个功能齐全的布局,而无需过多担心 HTML 的结构。
对于固定宽度布局,CSS 网格和 Flexbox 的工作流程是怎样的?
以下是HTML:
<!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">
<meta name="description" content="">
<meta name="author" content="">
<title>Test Grid Layouts</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<header>
<nav>
<div id="logo">Using Grid</div>
<ul>
<li><a href="#">About</a></li>
<li><a href="#">Blog</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
</header>
<main>
<div class="content">
<section class="hero">
<h3>Color Me Black</h3>
</section>
<article>
<h1>Title</h1>
<p>I love content!</p>
</article>
</div>
</main>
<footer>
<nav>
<div class="siteinfo">Made by Angelo</div>
</nav>
</footer>
</div>
</body>
</html>
还有CSS:
html, body {
margin: 0;
padding: 0;
height: 100%;
font-family: 'Roboto', 'Helvetica', sans-serif;
}
.container {
display: grid;
min-height: 100%;
grid-template-rows: 48px [stage] auto 48px;
grid-template-columns: 100%;
}
#logo {
color: #FFFFFF;
font-size: 1.5em;
}
header {
display: grid;
grid-template-columns: auto [head-center] 832px auto;
height: 48px;
background-color: #000000;
}
header > nav {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
grid-column-start: head-center;
grid-column-end: span 1;
}
header > nav ul {
margin: 0 0 0 auto;
}
header > nav ul li {
display: inline;
padding-left: 8px;
}
header > nav ul li a {
color: #FFFFFF;
text-decoration: none;
text-transform: uppercase;
}
header > nav ul li a:hover {
color: #AAAAAA;
}
main {
display: grid;
grid-template-columns: auto [main] 832px auto;
grid-template-rows: auto;
grid-row-start: stage;
grid-row-end: span 1;
}
main > div.content {
grid-column-start: main;
grid-column-end: span 1;
}
main > div.content .hero {
height: 300px;
width: 100%;
background-color: #000000;
color: #FFFFFF;
}
main > div.content .hero h3 {
padding: 16px;
}
footer {
display: grid;
grid-template-columns: auto [foot-center] 832px auto;
grid-template-rows: 48px;
background-color: #000000;
}
footer > nav {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-end;
align-items: center;
grid-column-start: foot-center;
grid-column-end: span 1;
}
footer > nav > .siteinfo {
color: #FFFFFF;
}
我这里还有一些其他巧妙的东西,可以让事物看起来更赏心悦目,但我们应该真正关注的是它在哪里display: grid被display: flex使用。
该.container元素是我们的顶层网格:
.container {
display: grid;
min-height: 100%;
grid-template-rows: 48px [stage] auto 48px;
grid-template-columns: 100%;
}
在这里,我们用grid-template-rows它来定义顶级行(从上到下)。这些行可以是固定大小、百分比或任意值auto。属性下的每个规范都按定义顺序映射到一个子项。例如,第一个48px条目是我的第一行,auto(别名为stage)是我的第二行,而是48px我的最后一行。我还指定了我希望它grid-template-columns扩展到容器的整个宽度。
现在我已经完成了这一步,我必须考虑从该网格元素创建的直接子元素,因为我应用的所有属性都是应用于该父元素的直接子元素。
这个父元素的子元素(我的网格项).container是header,main和footer。我定义了这些项的属性,以告诉它们在网格中的位置。
我们来看一下main:
main {
display: grid;
grid-template-columns: auto [main] 832px auto;
grid-template-rows: auto;
grid-row-start: stage;
grid-row-end: span 1;
}
我在这里做了几件事。我在顶层.container网格下定义了另一个网格,并告诉这个网格项从stage行的起始位置开始,然后span向下延伸(或)一个单元格。如果我没有将起始行别名化为stage,那么我就必须计算出要从多少行开始,然后输入这个数字(在本例中,它将是2)。
基本上就是这样。虽然它不像 HTML<table>标签那样复杂,但它们的放置逻辑非常相似。你可以把它想象成colspan和上面的属性rowspan非常相似span。
对我来说,最重要的两个概念是grid定义布局的父元素和定义每个“项目”的子元素。项目是指映射到网格中特定位置的内容的 DOM 元素。
你可以通过嵌套grid来实现更复杂的布局。我这样做是为了让页眉和页脚的背景能够横跨整个页面宽度,同时还能在main元素内部保持一个“内部”网格,使内容居中,并且边距会自动调整。
我以前grid管理布局时,也 flex 管理布局中子元素的定位行为。这不仅包括垂直和水平定位,还包括子元素之间的相对间距,甚至顺序。Flexbox 在这方面表现出色,可以(也确实)用于布局,但随着 DOM 变得越来越复杂,它最终会显得非常不规范。因此,grid如果您要设计大型组件,请使用其他方法。
此外 grid ,还有更多需要考虑的因素,例如线条、轨道、区域和单元格。我还大量使用了别名。这些都是你应该尝试并理解的内容。
所以最好自己动手尝试。直接将 HTML 代码复制到一个文件中并保存,index.html然后将 CSS 代码另存为另一个styles.css文件,最后将它们放在一个文件夹中。
假设您已安装 Python 3 并且拥有可用的 Unix shell,则可以运行以下程序:
$ cd YOUR_FOLDER
$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
然后打开浏览器,http://localhost:8000使用浏览器内置的开发者控制台调整 CSS 值,或者直接编辑磁盘上的文件,每次更改后刷新浏览器。
另外,试试移动端的视图。你会很快发现宽度是固定的。你能让它以流式或响应式的方式工作吗?提示:看看这个博客网站的 HTML 和 CSS 代码。
总之
网格布局有很多用途。你可以添加媒体查询,还可以根据需要实现完全流式布局。大多数现代浏览器都支持网格和弹性布局。你可以查看网格指南、弹性布局指南或规范本身以获取更多信息,最重要的是——抛弃你的临时方案!
参考
- CSS Grid规范:放置元素
- CSS 2 规范:最小和最大高度:'min-height' 和 'max-height'