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

xiaoxiao2021-02-28  59

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)

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

创建可读的html标签,拥有完善的层次结构和语义化标签。 对所有可能的屏幕宽度,创建响应式的单栏布局 应用先进的布局方式和功能(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) {}


未完待续

转载请注明原文地址: https://www.6miu.com/read-58808.html

最新回复(0)