工业化、响应式的的CSS3 grid布局应用及其向后兼容问题-- 上 --(翻译自smashingmagazine,有删改)

gird布局的支持性仍然不够完善,但作为二维布局的利器,足以轻而易举地做出一些原本需要耗费时间的事情。正如a complete guide to grid的作者所说,在实际工作中运用grid布局只是一个时间问题,而现在正是学习它的好时机。

安卓和ios,desktop上ie11+都已支持grid布局。更多细节可在caniuse查到。
这里写图片描述

网格布局的基础知识参照此篇

英语好的同学请移步此篇,更详细哟:
A complete guide to Grid

本文来源 :
building-production-ready-css-grid-layout

如图,想要完成这样的布局。上下的.header, footer的宽度占到100%,中间的彩色主题占到了宽度的2/3,又可以分为两列。第一列为main-content和sidebar,宽度之比为2:1;第二列各占50%。

你可能会想到用margin-left/right设为auto来使其居中,或使用flex布局来设定main container, 每个元素给予一个flex 值。在flex box出现之前,可能会用float来将其分别在左或在右。

现在,把你这些网页设计想法抛至一旁,把它当做用你最喜欢的设计布局方式来思考这个问题。什么是第一时间浮现在脑海中的?格子。(grid)。四行,八列的格子。

在印刷环境下,你不会用margins来居中,也不会用flex来布局,而是会把元素排布在一个个的格子中。header,content, sidebar 和 footer,每一个都占据了一行,header 和 footer 占据了所有的 八列,而content占据了第二列到第五列,侧栏sidebar则占据了第6列到第7列。

这里写图片描述

通过css的gird布局,你现在也可以在浏览器中做相同的事情了。

.site {
    display: grid;
    grid-template-columns: 1fr repeat(6, minmax(auto, 10em)) 1fr;
    grid-template-rows: minmax(1em, auto) 1fr auto minmax(1em, auto);
}

.masthead,
.colophon {
    grid-column: span 8;
}

.main-content {
    grid-column: 2/6;
}

.sidebar {
    grid-column: 6/8;
}

.twin {
    grid-column: 2/5;
    grid-row: 3/4;
}

.twin:last-of-type {
    grid-column: 5/8;
}

CSS 格子布局汲取了印刷式格子布局的精华,并用浏览器的视窗功能提高了它的灵活性。中央的6列将通过CSS的minmax() 函数给予一个最大宽度值,而第一列和最后一列将用fr为单位设置,都设为1fr,表示以特定比率(在这里是1:1)平分了剩余空间(fraction factor)。现在我们得到的是浏览器中的一个中央居中的响应式格子布局。而且,由于它完全使用CSS来完成,可以用媒体查询(media queries)来为不同的视窗宽度改变布局样式。

正如 flexbox一样,格子布局尊重文字的方向。所以,如果dir被设为rtl的话,布局会镜像改变,将侧栏sidebar放到左边。(谷歌亲测无效。。。可能对dir的支持不好)


新观念:css格子布局模式

正如上文中的例子,在开始格子布局前,首先要做的是把原有的设计习惯弃之一旁,在很多情况下,那些已经建立起来的设计习惯是些旁门左道(hacks), 用于来弥补CSS作为布局工具的缺陷。我认为,css grid 是第一个真正的css布局模块。它能在二维空间布局,并且将任意元素放到单元格(cell)或单元格的组合中。这需要一套之前截然不同的崭新观念,你不再问自己,怎样让纵向流的内容显示出被框在格子中的样子,而是简单地定义格子,并将每一块内容填入其中。

让我们再来看一个例子。首先想想单列布局,包括了宽度压缩、中央居中的内容和宽度占满的图片及背景。

这里写图片描述

右侧的格子布局则包含了8行,4列,你可以将任意元素放到想要的格子中去。然而,格子的载体(那个被设置为display:gird)会将元素们作为直接后代,即grid items。这意味着,你不能创建一个单独的格子布局。而是必须在组件级别构造格子,有效地把多个格子设置为同一特性。

边注:格子布局中包括一个亚格子的概念,允许后代元素继承父母格子的样式并用到它的孩子上。subgrid特性已经被移到了规定的level 2级别,即在可预见的将来,浏览器上还无法运用。关于subgrid,可以参见这篇文章 subgrid currently stands .

为了在浏览器上创建格子布局,你还需要运用其他工具和设置,就像我们接下来看到的那样。

如果你什么都不做的话,每一部分都会被拉伸到与Box等宽。 对每一个居中对齐(center-aligned)的内容部分,加上.grid类名,并创建一个4列的格子,把需要居中对齐的部分装到中央的2列中。第三部分具有三个并列的buckets,可以用flex 布局来完成对这一部分的布局。

@media screen and (min-width: 700px) {
  @supports (display: flex) {

    .buckets ul {
      display: flex;
      justify-content: space-around;
    }

    .buckets li {
      width: 31%;
    }

  }
}

最后一部分是两个占满宽度的横条,每个横条分别由两个单独的格子元素构成,每个占两列,可以用grid-column:span 2来完成,意思是每个格子延展了两列的宽度,并且允许让格子自动地掌控剩余的事情。(我的理解是自适应。)
整体代码如下:

/* Four-column layout. Two center columns have a total max-width of 50em: */
.grid {
    display: grid;
    grid-template-columns: 1fr repeat(2, minmax(auto, 25em)) 1fr;
}
/* Center items by placing them in the two center columns: */
.splash-content,
.more-content,
.buckets ul {
    grid-column: 2/4;
}
/* Use automatic grid placement + span to let each item span two columns: */
.twin,
.colophon aside {
    grid-column: span 2;
}

这是在线版本的地址:live version on Codepen

上面的例子很好地说明了css grid布局可以被用于普通的布局任务,如全屏宽的部分。但也有一些局限。像之前解释的,最佳情况下希望仅绘制一个格子,并运用subgrid来处理所有的部分和子部分。然而,只有第一级的载体后代(first-level descendants of the container whose display property set to grid)可以被定位到格子上,而subgrid属性还不能再浏览器上得到支持。所以我们被迫用你所见到的方式来处理。好消息是,这总归比原来的旧方式来得好,而且写出的css 干净、可读。

个人的理解是,grid还是比较适用于大屏幕,二维布局方便,手机上本来宽度就窄,单栏式布局用display flex 足矣


正式工作中运用grid布局全过程

现在,你应该已经接受css grid布局概念了, 我么你来看看在生产中该怎么运用这一模式。

不止是布局模块,css grid 布局是一张邀请函,让网页设计和开发回到我们的初心上来,即创建可运用的,易于扩展的,解决方案,让内容放在最合适的位置上。

而前端工作的核心原则是,首先,让它功发挥作用,其次,要做的漂亮,而后者绝不能阻碍了前者。(first make it accessible, then make it fancy, and make sure the fancy doesn’t break accessiblity

我们也需要考虑响应式,跨浏览器和跨终端平台的兼容性方案,以及向前兼容。总之,最后的解决方案大致如此:

  1. 创建可读的html标签,拥有完善的层次结构和语义化标签。
  2. 对所有可能的屏幕宽度,创建响应式的单栏布局
  3. 应用先进的布局方式和功能(grid, flex, javascript,等等)

最终,将得到一个可以应用在任意浏览器或平台上的功能完善的解决方案,同时采取了最新技术的优点。

向后兼容和浏览器支持

我觉得这部分基本是扯淡,大意就是,零向后兼容,浏览器支持也差得一逼,完全靠语义完善的html 标签撑着能让人看懂,挑两个重点段翻译吧

css grid 是一个布局模式,它使得我们在不打乱来源顺序的情况下,改变文档的布局。换句话说,CSS grid 只是纯粹的视图工具,正确运用的话,对文档内容之间的交互并没有任何影响。从这点出发,可以得到一个简单但令人惊讶的的结论,在老浏览器上如果缺少CSS grid 的支持,并不会影响到用户的体验,只是造成了另一种不同的体验而已。

一言以蔽之,我们应当运用css grid 布局来造成视觉上和布局上的提升,而不是对内容的语义性意义做出修改。参见MDN上的这篇文章css grid layout and accessibility,(也许GRID在表现和语义的分离上走得太远了一些?毕竟tab键和逻辑顺序不随着视觉变化还是有点怪怪的。。。)

这特么不是扯是什么。。。。。无语了。。。

在wordpress主题下使用css grid布局的例子

 作者大力推荐使用firefox及其开发者工具[grid inspector tool](https://www.mozilla.org/en-US/developer/css-grid/),打开开发者工具,选择点击的那个图标(通常在第一个),鼠标移到哪里,就能看到哪里的格子了。
0. 结构化布局草稿

在开始项目之前,我先绘制了这个主题下主要内容的结构化布局草稿。你会注意到,这些草稿没有包含大小或其他的具体细则,他们只是勾勒了整体布局和相应格子位置的轮廓。

对手机之类的窄屏幕,或不支持grid布局的老式浏览器,布局是一个居中的单列,内容与文档的层次一致。对现代浏览器,则有两个主要的布局。

  • 列表和档案视图在格式中呈现了张贴的告示,而特别告示占据了其他告示的两倍空间。(index and archive views show published posts in a grid pattern , where featured posts take up twice as much space as other posts)

    这里写图片描述

  • 一个单独的告示和页面视图会按照内容的次序排列,并且由视图的宽度决定其布局(a single post and page view with grids would change the layout and displayed order of content depending on the viewport’s width)。

这里写图片描述

1. 创建有层次、语义化的html结构

由于CSS的历史局限性,很多框架都需要严重得依赖于层层包裹的容器
来把元素分门别类,从而让开发者易于定位诸如主要内容旁边的侧栏这样的元素。简化的层次结构视图如下。

这里写图片描述

格子容器把它的直接后代当做单独的格子项来对待,免除了用于浮动和清除浮动的元素。从而“拉平”了html结构,使之更加清晰易读。

这里写图片描述

在实际项目中,去掉这些冗余的div意味着去掉了大量的 php文件,其逻辑结构如下:


<div id='page' class='site'>
<header id='masthead' class='site-header' role='banner'></header>
<!-- role属性作用是告诉Accessibility类应用(比如屏幕朗读程序,为盲人提供的访问网络的便利程序),这个元素所扮演的角色,主要是供残疾人使用。使用role可以增强文本的可读性和语义化。
在html5元素内,标签本身就是有语义的,因此role是不必添加的,至少是不推荐的,但是bootstrap的案例内很多都是有类似的属性和声明的,目的是为了兼容老版本的浏览器(用户代理),如果你的代码使用了html5标签,并且不准备支持老版本的浏览器,不妨不使用role标签。
 -->
 <main id='main' class='main'></main>
 <aside id='secondary' class='widget-area'></aside>
 <footer id='colophon' class='site-footer'></footer>
</div>
2. 创建响应式单列布局,适应于任意的屏幕宽度

在应用新样式之前,首先要清理干净原有的CSS浮动布局。一般会在元素上加伪元素,用于clearfix。但在grid布局或flex布局中,这些不可见的伪元素也会为做item之一排布。因此,如果需要清除特定元素的浮动,应该有个专门的.clearfix的类,并对它创建一系列CSS规则。Clearfix是一个hack,可以绕过浮动和清除浮动的问题,这应当作为优雅退化的一部分。

从320px开始,逐渐加宽屏幕的宽度,利用可用空间。结果应是一个响应式的单栏布局,适应于任何可能的屏幕宽度。

考虑到兼容性,使用媒体查询来检查是否支持:
@supports(display:grid){}
唯一的挑战是microsoft edge浏览器,始终用旧式的grid方法的唯一一个现代浏览器。对@supports查询它将返回真,但实际grid支持漏洞百出、且并不规范。问题主要出在对于grid-template-areas和grid-area,以及minmax()函数的不支持,因此,需要把媒体查询语句改为

@supports (grid-area:auto) {}


未完待续

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值