by Chris House
译者:若愚老师
想要更好的阅读体验可在饥人谷技术博客 查看原文
要看懂这篇文章,推荐先简单过一遍姊妹篇 CSS Grid 系列(上)-Grid布局完整指南css
当我开始一个项目,并开始计划如何布局主页时,个人大脑复现出浮动和定位。有些人可能会使用 Bootstrap 或其余框架。 那是由于这是2016年,咱们一直在用这些方法来作布局。 但假设咱们乘坐时光机来到2018年,全部主流浏览器都支持CSS Grid 布局模块。此时咱们的页面布局模式已经彻底改变,CSS的功能最终强大到能轻松实现咱们的设计目标,这是一个web开发人员最美好的时代。如今,让咱们使用超赞的工具——Grid布局来建立一个主页。html
下面是咱们将要实现的页面前端
在咱们开始编码以前,咱们须要进入网格的思惟模式。 第一步是观察咱们的设计稿,并将其划分为主要的网格组件。 如下是我为此设计作的划分:web
你会发现整个页面分为7个顶级网格区域。 我之因此说“顶级”是由于咱们能够在其内部继续嵌套网格,这正是咱们将要对hero部分所作的事:面试
这是HTML的基本结构。 稍后我会显示整个完成的文件,但如今我已经省去了大部分的细节。 这里要注意的重要部分是做为 body
的直接后代的7个元素:top-bar
、main-header
、hero
、 blog-posts
、 news
、 side-bar
以及 main-footer
。 body
将成为咱们的网格容器(grid container),它的孩子将成为网格项(grid items)。chrome
正如刚刚提到的,咱们也将设置 hero
做为网格容器。 它有两个孩子,将做为网格项:message
和 award
。segmentfault
<body> <header class="top-bar"> <!-- social links and contact info --> </header> <header class="main-header"> <!-- logo and main navigation --> </header> <section class="hero"> <div class="message"> <!-- circular element --> </div> <div class="award"> <!-- award image and quote --> </div> </section> <section class="blog-posts"> <!-- blog posts and excerpts --> </section> <section class="news"> <!-- news headlines and excerpts --> </section> <aside class="side-bar"> <!-- critter of the month info --> </aside> <footer class="main-footer"> <!-- footer menu and copyright --> </footer> </body>
Okey,咱们按照这种方式讲解,教程中咱们不会展现全部使用到的CSS,在文章的最后我会展现最终完整的文件。如今咱们只关注吸引咱们的网格部分以及任何与它直接相关的样式便可。浏览器
咱们首先在body
上定义主网格容器:微信
body{ display: grid; grid-template-columns: 12% auto 400px 12%; grid-template-rows: auto auto 950px auto auto auto; }
咱们刚刚建立了一个4列6行的网格,第一列和最后一列将做为主内容两侧的填充。 我把第三列设置为400px,由于这是咱们将要放置side-bar
元素的地方,咱们但愿这是一个固定的宽度。 hero
元素(第三行)的固定高度为950px。框架
如今咱们使用grid-template-areas
来定义某个网格区域会跑到哪里。 这是很是有趣的部分:
body{ display: grid; grid-template-columns: 12% auto 400px 12%; grid-template-rows: auto auto 950px auto auto auto; grid-template-areas: "top-bar top-bar top-bar top-bar" "main-header main-header main-header main-header" "hero hero hero hero" ". blog-posts side-bar ." ". news side-bar ." "main-footer main-footer main-footer main-footer"; }
grid-template-areas
让咱们能把元素放在任何想要放置的地方,而且对于元素的布局该属性给咱们提供一个不错的可视化。 值得注意的是,这里使用的值(top-bar
,main-header
,hero
等)不是指那些元素的类名,而是指咱们用grid-area
属性给它们起的名字,下一步咱们将对它们命名。
当网格区域名称重复时,该元素将跨越这些列/行。 例如,top-bar
横跨四列,side-bar
横跨四行和五行。 .
号表明空单元格。若是你回头看看上面的完整设计,您会看到这个定义如何与咱们的网格模式相匹配。
假设咱们已经应用了咱们全部的样式,但尚未为网格项分配网格区域名称,到目前为止咱们的页面看起来还不太好:
在将网格区域名称分配给网格项以前,网格将根据它们的源顺序自动将咱们的元素放置在网格中。 显然这不是咱们想要的。 为了使咱们的布局按预期工做,咱们须要定义咱们的网格区域。因此咱们继续往下走:
.top-bar{ grid-area: top-bar; } .main-header{ grid-area: main-header; } .hero{ grid-area: hero; } .blog-posts{ grid-area: blog-posts; } .news{ grid-area: news; } .side-bar{ grid-area: side-bar; } .main-footer{ grid-area: main-footer; }
须要注意的是这些名称能够随意设置。 为了方便,我选择了让它们与类名相匹配。
如今,咱们已经为网格项分配了网格区域名称,它们将在被放置在网格中合适的位置。 这一步带来的变化很大:
除了 hero
部分中的网格项外,全部内容都彻底按照须要正确放置,咱们差很少要完成了。
可是在咱们修复 hero
部分以前,我想解释一下一些难以理解的地方:主要内容两边的填充区域的设置。 做为提醒,咱们再次把刚刚的设置搬过来,用以下方式调整列:
body{ grid-template-columns: 12% auto 400px 12%; }
设置为12%的两列用于填充主要内容两边的空白,可是它们仅用于第四行和第五行。 回想一下,咱们告诉咱们的top-bar
、main-header
、hero
和main-footer
元素跨越全部列,包括这两个“填充”列。 咱们为何这样作? 由于咱们但愿这些元素的背景色横跨越整个视窗宽度,且任何一侧都没有空白。 咱们只想在 blog-post
/news
和sidebar
元素周围留出空白(第四行和第五行)。
为了让元素水平覆盖整个宽度,同时让元素里面的内容保存必定的padding,咱们须要显示地在这些元素上设置padding:
.top-bar{ padding: 4px 12%; } .main-header{ padding: 12px 12%; } .hero{ padding: 55px 12% 0 12%; } .main-footer{ padding: 25px 12%; }
咱们给元素设置左右 padding 为12%,这和grid-template-areas
定义中的第一列和最后一列的宽度是同样的。 如今,须要填充整个宽度的元素最终呈现的结果是,背景横跨水平宽度,但其内容在两侧都预留出12%的空白。 很赞!
好了,让咱们来修复 hero
部分。 这也将是一个网格容器,所以咱们把它定义为一个网格,就像刚刚作过的那样:
.hero{ display: grid; grid-template-columns: auto 1fr auto; grid-template-rows: auto auto auto; grid-template-areas: ". . award" "message . . " ". . . "; }
这是一个3×3的网格,除了中间的列,其它都设置为 auto
。 咱们给中间一列大小设为1fr
,由于咱们但愿在第一列和最后一列用东西填充后,剩下的空间彻底须要彻底填满。
hero
中只有两个元素:message
和award
。 咱们要message
占据第二行的第一列,咱们要award
占据第一行的第三列。因此咱们的完整网格定义应该以下所示:
.hero{ display: grid; grid-template-columns: auto 1fr auto; grid-template-rows: auto auto auto; grid-template-areas: ". . award" "message . . " ". . . "; }
下面咱们所要作的就是命名咱们的元素:
.message{ grid-area: message; } .award{ grid-area: award; }
就这样,message
和award
卡入到位,咱们的页面完成:
CSS Grid 使用媒体查询让从新排列整个布局变得很是简单。你所作的就是从新放置你的网格项。如今回到咱们的设计,简单起见,咱们只对两个宽度临界值作响应式处理,1600px 和 1050px。咱们须要对一些元素(padding、margin等)进行一些小的样式调整,可是我不会把全部的样式调整都所有展现在这里。后面我会放出完整的代码,如今咱们只须要关注关注网格相关的东西便可。
1600px 这个临界点的处理比较简单,当浏览器宽度到底1600px时咱们将减小网站外部填充的地方。 之因此选择1600px,是到了这个宽度后12%填充看起来不太合适。为了解决这个问题,咱们须要作的是在body上改变grid-template-columns
的值,将第一列和最后一列减小到2%。 咱们还须要调整其余元素的填充以匹配:
@media (max-width: 1600px) { body{ grid-template-columns: 2% auto 400px 2%; } .top-bar{ padding: 4px 2%; } .main-header{ padding: 12px 2%; } .hero{ padding: 55px 2% 0 2%; } .main-footer{ padding: 25px 2%; } }
对于下一个临界值,咱们对网格项从新排列,使它们排列在一个列中。 再次回头看看咱们原来的代码是如何对body进行设置的:
body{ display: grid; grid-template-columns: 12% auto 400px 12%; grid-template-rows: auto auto 950px auto auto auto; grid-template-areas: "top-bar top-bar top-bar top-bar" "main-header main-header main-header main-header" "hero hero hero hero" ". blog-posts side-bar ." ". news side-bar ." "main-footer main-footer main-footer main-footer"; }
下面是从新设置的媒体查询:
@media (max-width: 1050px) { body{ grid-template-columns: 3% auto 3%; grid-template-rows: auto auto auto auto auto auto auto; grid-template-areas: "top-bar top-bar top-bar" "main-header main-header main-header" "hero hero hero" ". blog-posts ." ". news ." ". side-bar ." "main-footer main-footer main-footer"; } }
咱们在这里作了一些重要的改变:将列数从四个减小到三个,将第一列和最后一列的值改成3%(3%在较窄的宽度上优于2%),添加了 附加行,将全部行的长度改成auto
,并将side-bar
移动到本身的行。 如今咱们的页面元素很适合在较窄的宽度下展现:
下面是咱们的主页,以及完整的HTML和CSS文件。 你须要一个支持grid的浏览器来查看预览。 我建议启用Experimental Web Platform Features标志的Chrome 49+(地址栏输入 chrome:// flags ,并向下滚动到“Experimental Web Platform Features”)。
下面的嵌入式页面默认会以移动视图展现,能够点击“Edit on Codepen”在页面全宽下展现不一样的效果:
在 CodePen 查看效果 Building a Home Page with Grid by Chris House (@chrishouse) .
补充: 基本布局代码
加微信号: astak10或者长按识别下方二维码进入前端技术交流群 ,暗号:写代码啦
每日一题,每周资源推荐,精彩博客推荐,工做、笔试、面试经验交流解答,免费直播课,群友轻分享... ,数不尽的福利免费送