一篇全面的CSS布局学习指南 [译]

本文来自SmashingMagazine上一篇很是不错的CSS布局综述类文章,汇总了各种CSS布局技术,并提供了这些技术深度阅读的连接。故而翻译过来和你们分享,原文连接在文末,感谢做者Rachel Andrew。css

引言

不管你是一个想要学习CSS布局的新手,仍是一个比较有经验但想要进一步巩固与了解最新CSS布局知识的前端开发者,这篇指南都能帮你全面了解现在CSS布局发展的现状。html

在过去的许多年中,正如翻天覆地的前端开发通常,CSS布局也产生了巨大的变化。如今咱们有须要可选的CSS布局方式来开发咱们的网站,这也就要求咱们对这些方式做出选择。在这片文章里,我会介绍各类CSS布局的基本使用方式以及使用的目的。前端

若是你仍是CSS方面的新手而且想要了解什么是最好的布局方法,这篇文章正式你所须要的;固然,若是你是一位比较有经验的开发者,想要了解一些关于CSS布局的最新知识,这篇文章也不容错过。固然,我不会将各种技术的细枝末节都放到这篇文章里(不然能够写一本书了),而是对各种技术作一个基本的概述,同时会给你们提供相关连接来进一步学习。git

喜欢的朋友欢迎关注个人博客RSS 订阅github


1. 正常文档流(Normal Flow)

若是你打开一个没有用任何CSS来改变页面布局的网页,那么网页元素就会排列在一个正常流(normal flow)之中。在正常流中,元素盒子(boxes)会基于文档的写做模式(writing mode)一个接一个地排列。这就意味着,若是你的写做模式是水平方向的(句子是从左到右或从右到左书写),正常流会垂直地一个接一个排列页面的块级元素。web

固然,若是你是在一个垂直方向的写做模式下,句子是垂直方向书写的,因此块级元素会水平方法排列。spring

Block and Inline Directions change with Writing Mode

正常流是一种最基础的布局:当你为文档应用了CSS、建立了某些CSS布局,你实际上是让这些块作了一个正常文档流以外的“事”。浏览器

1.1. 经过页面结构来发挥正常文档流的优点

经过确保你书写的页面具备良好的页面结构(well-structured manner),你能够最大程度利用正常流所带来的优点。试想一下,若是浏览器中没有正常流,那么你建立的元素都会堆积在浏览器的右上角。这就意味着你必须指定全部的元素的布局方式。markdown

有了正常流,即便CSS加载失败了,用户仍然能阅读你的页面内容;同时,一些不使用CSS的工具(例如一些阅读器)会按照元素在文档中的位置来读取页面内容。从 可用性(accessibility) 角度来看,这无疑是很是有帮助的,同时也让开发者轻松了一些。若是你的内容顺序和用户预期的阅读顺序一致,你就不须要为了将元素调整到正确的位置而进行大量的布局调整。当你继续读下去会发现,使用新的布局方式是如何让页面布局事半功倍的。ide

所以,在思考如何布局以前,你须要认真思考你的文档结构,以及你但愿用户以何种顺序来阅读文档中的内容。

1.2. 脱离正常文档流

一旦你有了一个结构良好的页面,你就须要去决定如何利用它并将它变为咱们须要的布局结构。这会涉及到 脱离正常文档流(moving away from normal flow),即本文后续的部份内容。咱们有许多布局“利器”可使用,其中第一个就是float,它是一个描述什么是脱离正常文档流的很是好的例子。


2. 浮动(Float)

浮动被用来将盒子(box)置于左侧或右侧,同时让内容环绕其展现。

要让一个元素进行浮动,须要为该元素设置一个值为leftrightfloat属性。默认值为none

.item {
    float: left
}
复制代码

值得强调的是,当你使某个元素浮动并让文字环绕它时,内容的line box被截断了。若是你让一个元素浮动,同时为紧跟着的包含文本的元素设置一个背景色,你会发现背景色会出如今浮动元素下方。

The background color on the content runs under the float

若是你想要在浮动元素和环绕的文本之间建立边距,你须要给浮动元素设置外边距。在文本元素上设置外边距只会让其相对于容器缩进。例如在下面这个例子中,你就须要为左侧浮动的图片设置右边距和下边距。

<div class="container">
  <div class="item"></div>
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
}

.item {
  width: 100px;
  height: 100px;
  float: left;
  margin: 0 20px 20px 0;
  background-color: rgba(111,41,97,.3);
}
复制代码

2.1. 清除浮动

一旦你对一个元素应用了浮动,全部接下来的元素都会环绕它直到内容处于它下方且开始应用正常文档流。若是你想要避免这种状况,能够手动去清除浮动。

当你不想要某个元素受到其以前的浮动元素影响时,为其添加clear属性便可。使用left值能够清除左浮动效果,right值为右浮动,both则会清除左右浮动。

.clear {
    clear: both;
}
复制代码

可是,当你发如今容器内有了一个浮动元素,同时容器文本内容太短时就会出现问题。文本盒子会被绘制在浮动元素下,而后接下来的部分会以正常流绘制在其后。

The box around the text does not clear the float

为了不这种状况,咱们须要为容器中某个元素应用clear属性。咱们能够在容器最后添加一个空元素并设置clear属性。可是在某些状况下可能没法使用这种方式(例如一些CMS系统生成的页面)。所以,最多见的清除浮动的hack方案是:在容器内添加一个CSS伪元素,并将其clear属性设置为both。

<div class="container">
  <div class="item"></div>
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra.</p>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
}

.item {
  width: 100px;
  height: 100px;
  float: left;
  margin: 0 20px 20px 0;
  background-color: rgba(111,41,97,.3);
}

.container::after {
  content: "";
  display: table;
  clear: both;
}
复制代码

example: Smashing Guide to Layout: clearfix on Codepen

2.2. 块级格式化上下文(Block Formatting Context)

清除浮动的另外一个方法是在容器内建立BFC。一个BFC元素彻底包裹住了它内部的全部元素,包括内部的浮动元素,保证浮动元素不会超出其底部。建立BFC的方式有不少种,其中最经常使用的一种清除浮动的方式是为元素设置除visible(默认)以外的overflow属性值。

.container {
    overflow: auto;
}
复制代码

像上面这样使用overflow通常状况下是有效的。然而,在某些状况下,这可能会带来一些阴影的截断或是非预期的滚动条。同时它也使你的CSS变得不那么直观:设置overflow是由于你想要展现滚动条仍是仅仅为了获取清除浮动的能力呢?

为了使清除浮动的意图更加直观,而且避免BFC的负面影响,你可使用flow-root做为display属性的值。display: flow-root作的惟一的一件事就是去建立一个BFC,所以能够避免其余建立BFC方法带来的问题。

.container {
    display: flow-root;
}
复制代码

2.3. 浮动的一些遗留用法

在新的布局方式出现之前,float常常会被用来建立多栏布局。咱们会给一系列元素设置宽度而且将它们一个接一个进行浮动。经过为浮动元素设置一些精细的百分比大小能够建立相似网格的效果。

我不建议在当下仍然过分地使用这种方法。可是,在现有的网站中,这种方式仍然会存在许多年。所以,当你碰到一个页面里面处处是float的应用,能够肯定它就是用的这种技术。

2.4. 关于浮动与清除浮动的其余阅读资料


3. 定位(Positioning)

想要把一个元素从正常流中移除,或者改变其在正常文档流中的位置,可使用CSS中的position属性。当处于正常文档流时,元素的position属性为static。在块级维度上元素会一个接一个排列下去,当你滚动页面时元素也会随着滚动。

当你改变元素的position属性时,一般状况下你也会设置一些偏移量来使元素相对于参照点进行必定的移动。不一样的position值会产生不一样的参照点。

3.1. 相对定位(relative postioning)

若是一个元素具备属性position: relative,那么它偏移的参照位是其原先在正常文档流中的位置。你可使用top、left、bottom和right属性来相对其正常流位置进行移动。

.item {
    position: relative;
    bottom: 50px;
}
复制代码

注意,页面上的其余元素并不会因该元素的位置变化而受到影响。该元素在正常流中的位置会被保留,所以你须要本身去处理一些元素内容覆盖的状况。

<div class="container">
  
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  
  <div class="item"></div>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
}

.item {
  width: 100px;
  height: 100px;
  background-color: rgba(111,41,97,.3);
  position: relative;
  bottom: 50px;
}
复制代码

example: Smashing Guide to Layout: position: relative on Codepen

3.2. 绝对定位(absolute postioning)

给一个元素设置position: absolute属性能够将其彻底从正常流中移除。其本来占据的空间也会被移除。该元素会定位会相对于视口容器,除非其某个祖先元素也是定位元素(position值不为static)。

所以,当你为某个元素设置position: absolute时,首先发生的变化是该元素会定位在视口的左上角。你能够经过设置topleftbottomright偏移量属性来将元素移动到你想要的位置。

.item {
    position: absolute;
    top: 20px;
    right: 20px;
}
复制代码

一般状况下你并不但愿元素相对于视口进行定位,而是相对于容器元素。在这种状况下,你须要为容器元素设置一个除了默认static以外的值。

因为给一个元素设置position: relative并不会将其从正常流中移除,因此一般这是一个不错的选择。给你想要相对的容器元素设置position : relative,就可让绝对定位的元素相对其进行偏移。

<div class="container">
  
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  
  <div class="item"></div>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  position: relative;
}

.item {
  width: 100px;
  height: 100px;
  background-color: rgba(111,41,97,.3);
  position: absolute;
  top: 20px;
  left: 20px;
}
复制代码

example: Smashing Guide to Layout: position: absolute on Codepen

3.3. 固定定位(fixed positioning)

大多数状况下,position: fixed的元素会相对于视口定位,而且会从正常文档流中被移除,不会保留它所占据的空间。当页面滚动时,固定的元素会留在相对于视口的位置,而其余正常流中的内容则和一般同样滚动。

.item {
    position: fixed;
    top: 20px;
    left: 100px;
}
复制代码

当你想要一个固定导航栏一直停留在屏幕上时这会很是有效。和其余的position值同样,这也可能会形成一些元素被遮挡,须要当心保证页面内容的可读而不会被固定元素遮挡。

<div class="container">
  
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  
  <div class="item"></div>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
  
   <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
  
   <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  position: relative;
}

.item {
  width: 100px;
  height: 100px;
  background-color: rgba(111,41,97,.3);
  position: fixed;
  top: 20px;
  left: 20px;
}
复制代码

example: Smashing Guide to Layout: position: fixed on Codepen

为了使一个固定定位的元素不相对于视口进行定位,你须要为容器元素设置transformperspectivefilter三个属性之一(不为默认值none)。这样固定的元素就会相对于该块级元素偏移,而非视口。

3.4. STICKY 定位

设置position: sticky会让元素在页面滚动时如同在正常流中,但当其滚动到相对于视口的某个特定位置时就会固定在屏幕上,如同fixed通常。这个属性值是一个较新的CSS属性,在浏览器兼容性上会差一些,但在不兼容的浏览器中会被忽略并会退到正常的滚动状况。

.item {
    position: sticky;
    top: 0;
}
复制代码

下面的代码展现了如何建立一个很是流行导航栏效果:导航栏会随着页面滚动,而当导航栏滚动到页面顶部时则会固定在顶部位置。

<div class="container">
  
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  
  <div class="item"></div>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
  
   <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
  
   <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  position: relative;
}

.item {
  width: 100px;
  height: 30px;
  background-color: rgba(111,41,97,.3);
  position: sticky;
  top: 0;
  width: 100%;
}
复制代码

example: Smashing Guide to Layout: position: sticky on Codepen

3.5. 关于定位(positioning)的其余阅读资料


4. 弹性布局(Flex Layout)

弹性盒子(Flexbox)布局是一种为一维布局而设计的布局方法。一维的意思是你但愿内容是按行或者列来布局。你可使用display: flex来将元素变为弹性布局。

.container {
    display: flex;
}
复制代码

该容器的直接子元素会变为弹性项(flex item),并按行排列。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
}

.item {
  width: 100px;
  height: 100px;
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
复制代码

example: Smashing Guide to Layout: flex on Codepen

4.1. 弹性盒子的轴(axes)

在上面的例子中,咱们会称弹性项在行内是从起始位置开始排列,而不是说它们是左对齐。这些元素会按行排列是由于默认的flex-direction值为rowrow表明了文本的行文方向。因为咱们工做的环境是英文(中文也是如此),一种自左向右的语言,行的开始位置就是在左边,所以咱们的弹性项也是从左边开始的。所以flex-direction的值被定义为弹性盒子的主轴(main axis)。

交叉轴(cross axis)则是和主轴垂直的一条轴。若是你的flex-directionrow而且弹性项是按照行内方向排列的,那么交叉轴就是块级元素的排列方向。若是flex-directioncolumn那么弹性项就会以块级元素排列的方向排布,而后交叉轴就会变为row

若是你习惯于从主轴与交叉轴的角度来使用弹性盒子,那么一切会变得很是简单。

4.2. 方向和次序

弹性盒子模型让咱们能够经过为flex-direction属性设置row-reversecolumn-reverse值来改变主轴上弹性项的方向。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
  flex-direction: row-reverse;
}

.item {
  width: 100px;
  height: 100px;
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
复制代码

example: Smashing Guide to Layout: flex-direction on Codepen

固然,你也能够经过order属性来改变某一个弹性项的顺序。可是要特别注意,这可能会给那些经过键盘(而非鼠标或触屏)访问你的网站的用户带来一些麻烦,由于tab的顺序是页面内元素在源码中的顺序而非显示顺序。你能够阅读以后的“显示和文档顺序”部分来了解更多相关内容。

4.3. 一些Flex的属性

这些flex的属性是用来控制弹性项在主轴上空间大小的。这三个属性是:

  • flex-grow
  • flex-shrink
  • flex-basis

一般可使用它们的简写形式:flex。第一个值表明flex-grow,第二个是flex-shrink,而第三个则是flex-basis

.item {
    flex: 1 1 200px;
}
复制代码

flex-basis会为弹性项设置未拉伸和压缩时的初始大小。在上面的例子中,大小是200px,所以咱们会给每一个项200px的空间大小。可是大多数状况下容器元素大小不会正好被分为许多200px大小的项,而是可能有一些不足或剩余空间。flex-growflow-shrink属性容许咱们在容器大小不足或有空余时控制各个弹性项的大小。

若是flex-grow的值是任意的正数,那么弹性项会被容许拉伸来占据更多的空间。所以,在上面的例子中,当各项被设为200px后,全部多余的空间会被每一个弹性项平分并填满。

若是flex-shrink的值为任意的正数,那么当弹性项被设置了flex-basis后,元素溢出容器时会进行收缩。在上面这个CSS的例子中,若是容器空间不足,每一个弹性项会等比例缩放以适应容器的大小。

flex-growflex-shrink的值能够是任意的正数。一个具备较大flex-grow值的弹性项会在容器有剩余空间时拉伸更大的比例;而一个具备更大flex-shrink值的项则会在容器空间不足时被压缩的更多。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
}

.item {
  flex: 1 1 0;
  width: 100px;
  height: 100px;
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

.container :first-child {
  flex: 2 1 0; 
}
复制代码

example: Smashing Guide to Layout: flex properties on Codepen

理解这些属性是理解如何使用弹性布局的关键,下面列出的一些资源会帮助咱们进一步学习其中的细节。当你须要在容器的一个维度上拉伸或者压缩一些元素时,你能够考虑使用弹性盒子模型。若是你发现你正尝试在行和列两个维度上排列你的内容,你须要的是网格模型(grid),这时弹性盒子模型极可能不是最合适的工具了。

4.4. 关于弹性盒子布局的其余阅读资料


5. 网格布局(grid layout)

CSS网格布局(grid layout)是一种用来进行二维布局的技术。二维(two-dimesional)意味着你但愿按照行和列来排布你的内容。和弹性盒子相似,网格布局也须要设置一个display值。你能够为容器元素设置display: grid,而且使用grid-template-columnsgrid-template-rows属性来控制网格中的行与列。

.container {
    display: grid;
    grid-template-columns: 200px 200px 200px;
    grid-template-rows: 200px 200px;
}
复制代码

上面这段CSS会建立一个行列元素大小固定的网格。不过这也许并非你但愿的。默认值为auto,你能够认为这表明了“让格子尽量的大”。若是你每没有指定行(row track)的大小,全部添加进来的行内容大小都会被置为auto。一种经常使用的模式是为网格制定列宽度,可是容许网格按需添加行。

你可使用任意的长度单位或时百分比来设置行与列,同时你可使用为网格系统所创造的新的单位——frfr是一种弹性单位,它能够指定网格容器内的空间被如何划分。

网格会替你计算与分配空间,你不须要去计算元素的百分比去适应容器大小。在下面这个例子中,咱们使用fr来建立网格的列,这使得网格的列能够自适应。同时咱们还使用了grid-gap来保证元素间的间距(关于网格内元素与的间距会在“对齐”这一部分详细介绍)。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5<br>has more content.</div>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
复制代码

example: Smashing Guide to Layout: a simple grid on Codepen

5.1. 关于网格的一些术语

网格系统老是有两个轴:inline axis表示页面中文字的文字排列的方向,block axis表示页面中块级元素的排列方向。

一个被设置为display: grid的元素就是所谓的网格容器。在网格容器中会有网格线(grid line),网格线就是你在指定grid-template-columnsgrid-template-rows时网格中行列所生成的。网格中的最小单位(也就是被四条网格线截取生成的区域)被成为网格单元格(grid cell),进一步的,由若干个单元格组成的矩形区域被成为网格区域(grid area)。

Grid Lines run between each track of the grid.

Grid Tracks are between any two lines

Grid cells are the smallest unit on the grid, a Grid Area is one or more cells together making a rectangular area

5.2. 网格的自动排列规则

一旦你建立了网格,那么网格容器的直接子元素就会开始将它们本身一个一个地放置在网格的单元格中。子元素的放置是依据网格的自动排列规则(auto-placement rule)。这些规则确保了网格内元素是被安排在各个空的单元格中,而不会彼此遮盖。

网格中任何没有被进行定位的直接子元素都会根据自动排列规则进行放置。在下面这个列子中,我让每三个元素中的第一个占据两行,但仍然从起始行开始去自动排列。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

.container > div:nth-child(3n+1) {
  grid-row-end: span 2;
  background-color: rgba(193,225,237,.3);
  border: 2px solid rgba(193,225,237,.5);
}
复制代码

example: Smashing Guide to Layout: auto-placement on Codepen

5.3. 基于行/列的基本定位方法

定位网格元素最简单的方式是使用基于行/列(line)的定位方法,只需告诉浏览器从哪一排到哪一排来进行合并。例如,若是你须要一个2*2的网格区域,你能够将指定元素从第一行开始到第三行、从第一列开始到第三列,这样就能够覆盖到四个单元格。

.item {
    grid-column-start: 1;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 3;
}
复制代码

这些属性能够用缩写来表示:grid-columngrid-row,其中起一个值表明起始值,第二个值表明结束值。

.item {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
}
复制代码

你也可让网格项(grid item)占据同一个单元格。支持一些内容间会覆盖的设计。网格项会像一般网页中的元素那样叠起来,在html源码中下面的网格项会叠在其余元素上面。你仍然能够用z-index来控制它的堆叠顺序。

<div class="container">
  <div class="one">1</div>
  <div class="two">2</div>
  <div class="three">3</div>
  <div class="four">4</div>
  <div class="five">5</div>

</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
}

.container > div {
  padding: 10px;
}

.one {
  grid-column: 1 / 4;
  grid-row: 1;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

.two {
  grid-column: 1 / 3;
  grid-row: 2;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

.three {
  grid-column: 2 / 4;
  grid-row: 2 / 5;
  background-color: rgba(193,225,237,.3);
  border: 2px solid rgba(193,225,237,.5);
}

.four {
  grid-column: 1;
  grid-row: 4 ;
  background-color: rgba(193,225,237,.3);
  border: 2px solid rgba(193,225,237,.5);
}

.five {
  grid-column: 3 ;
  grid-row: 4 / 5;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
复制代码

example: Smashing Guide to Layout: line-based placement on Codepen

5.4. 经过命名区域来定位元素

你能够经过命名区域(named areas)来定位网格中的元素。要是用这种方式,你须要给每一个元素一个名字,而后经过grid-template-areas属性的值来描述布局方式。

.item1 {
    grid-area: a;
}

.item2 {
    grid-area: b;
}

.item3 {
    grid-area: c;
}

.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-areas: 
     "a a b b"
     "a a c c";
}
复制代码

使用这种方式有几个须要注意的点。若是你想要合并一些单元格做为你的网格项,你须要重复元素的名字。网格区域须要能造成一个完整的矩形 —— 每一个单元格都须要被填入一个值。若是你想要空出某些单元格,那就须要使用.这个值。例如在下面的CSS里我将最右下角的单元格留空。

.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-areas: 
     "a a b b"
     "a a c .";
}
复制代码

你也能够经过下面这个demo的代码来看看实际的布局效果。

<div class="container">
  <div class="one">1</div>
  <div class="two">2</div>
  <div class="three">3</div>
  <div class="four">4</div>
  <div class="five">5</div>

</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-rows: minmax(50px, auto);
  grid-gap: 20px;
  grid-template-areas: 
    "a a a"
    "b c c"
    ". . d"
    "e e d"
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

.one {
  grid-area: a;
}

.two {
  grid-area: b;
}

.three {
  grid-area: c;
}

.four {
  grid-area: d;
}

.five {
  grid-area: e;
}

复制代码

example: Smashing Guide to Layout: grid-template-areas on Codepen

5.5. 关于网格布局的其余阅读资料

这片文章只包括了CSS网格布局的一些初步内容,其中还有很是多的内容值得学习,下面的一些资料能够帮助你进一步学习。一些组件或整个页面的布局均可以使用网格。若是你须要在两个维度进行布局,网格布局是一个不错的选择 —— 不论须要布局的区域的大小。

我(做者)在Smashing Magazine也写一些文章来帮助你深刻理解各类网格的概念:


6. 显示顺序和文档顺序(visual and document order)

在文章的最开始,我建议你以从上到下的阅读顺序来组织你的文档顺序,这样会有助于可读性和CSS的布局方式。从咱们关于弹性盒子和CSS网格的简短介绍来看,你能够发现用这些布局方法可能会极大地改变页面展现的元素在文档中的顺序。这可能会致使一个隐含的问题。

在一些非可视化的应用场景中,浏览器会遵循文档源码来进行使用。所以,屏幕阅读器会读取文档的顺序,此外使用键盘tab键来浏览的用户访问文档的顺序是基于源码的顺序,而不是元素展现的顺序。许多屏幕阅读器的用户并不是彻底失明,他们可能在使用屏幕阅读器的同时也可以看到这些元素在文档的哪一个部分。在这些状况下,当与源码进行对比时,这种混乱的页面展示可能会使人充满迷惑。

当你改变了元素在文档中原来的顺序时,必定确保知道本身在作什么。若是你发现你本身正在CSS中从新排序你的元素,你应该去回头看看是否要从新组织你的页面元素。你能够经过使用tab访问来测试一下你的页面。

6.1. 关于显示顺序和文档顺序的其余阅读资料


7. 盒模型的生成(box generation)

你写在网页里的任何东西都会生成一个盒子(box),这篇文章讨论的全部东西其实都是如何可以使用CSS来按照你的设计布局这些盒子。然而,在某些状况下,你可能根本不想建立一个盒子。有两个display的属性值会帮你处理这种状况。

7.1. 不生成盒子或内容(display: none

若是你但愿元素以及它全部的内容(包括全部子元素)都不会生成,你可使用display: none。这样元素就不会被展现,而且不会保留其本该占有的空间。

.item {
    display: none;
}
复制代码

7.2 不生成该元素,可是生成其全部子元素(display: contents

display: contentdisplay的一个新的属性值。为一个元素应用display: content属性会致使其自身的盒子不生成但全部的子元素都会照常生成。这有什么用呢?试想一下,若是你但愿一个弹性布局或网格布局中的非直接子元素能应用这些布局,这就会很是有用。

在下面这个例子里,第一个弹性项包含了两个子元素,因为它被设为display: contents,它的盒子不会生成而且它的两个子元素会成为弹性项,并被看成弹性盒子容器的直接子元素来布局。

<div class="container">
  <div class="item">
    <div class="subitem">A</div>
    <div class="subitem">B</div>
  </div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
}

.item {
  flex: 1 1 200px;
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

.subitem {
  padding: 10px;
  background-color: rgba(193,225,237,.3);
  border: 2px solid rgba(193,225,237,.5);
}

.container .item:first-child {
  display: contents;
}
复制代码

example: Smashing Guide to Layout: display: contents on Codepen

7.3. 关于box generation的其余阅读资料


8. 对齐

在之前,要实现对齐每每会用到一些很"tricky"的方式,而且可以使用的方法也很是有限。随着CSS盒模型对齐(box alignment module)的出现,这一切都发生了变化。你将会使用它来控制网格容器与弹性盒子容器中的对齐。将来其余的各类布局方法都会应用这些对齐属性。盒模型对齐(box alignment specification)规范中的一系列详细属性以下:

  • justify-content
  • align-content
  • place-content
  • justify-items
  • align-items
  • place-items
  • justify-self
  • align-self
  • place-self
  • row-gap
  • column-gap
  • gap

因为不一样的布局模型有不一样的特性,所以用于不一样布局模型的对齐属性会有一些表现上的差别。让咱们来看看在一些简单的网格与弹性布局中对齐是如何工做的。

align-itemsjustify-items属性相对是align-selfjustify-self属性的一种批量形式。这些属性会控制与元素在其网格区域(grid area)中的对齐状况。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div class="special">5</div>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-rows: minmax(100px, auto);
  grid-gap: 20px;
  align-items: center;
  justify-items: start;
}

.special {
  grid-column: 2 / 4;
  align-self: end;
  justify-self: end;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
复制代码

example: Smashing Guide to Layout: Grid align-items, justify-items, align-self, justify-self on Codepen

align-contentjustify-content属性则会对网格中的行/列(tracks)进行对齐控制(网格容器中须要在排列完行/列元素后有多余的空间)。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  height: 300px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-auto-rows: minmax(100px, auto);
  grid-gap: 20px;
  align-content: space-between;
  justify-content: end;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
复制代码

example: Smashing Guide to Layout: Grid align-content, justify-content on Codepen

在弹性盒子中,align-itemsalign-self用来解决交叉轴上的对齐问题,而justify-content则用于解决主轴上空间的分配。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div class="special">3</div>
  <div>4</div>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  height: 300px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
}

.special {
  align-self: stretch;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
复制代码

example: Smashing Guide to Layout: Flex justify-content, align-items, align-self on Codepen

在交叉轴上,把弹性行(flex line)和额外空间包裹在弹性容器中以后,你就可使用align-content了。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>
复制代码
p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  height: 300px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
  flex-wrap: wrap;
  align-content: space-between;
}

.container > div {
  flex: 1 1 200px;
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
复制代码

example: Smashing Guide to Layout: Flex align-content on Codepen

下面的一些连接更细节地讨论了各种布局方法中的盒模型对齐。花些时间去理解对齐的工做原理是很是值得的,它对理解弹性盒子、网格布局以及将来的一些布局方法都会颇有帮助。

8.1. 行/列的间隔

一个多栏布局具备column-gap属性,到目前位置,网格布局具备grid-column-gaogrid-row-gapgrid-grid。这些如今都被从grid标准中删除而被添加进盒模型对齐中了。与此同时,grid-的前缀属性被重命名为column-gaprow-gapgap。浏览器会将带有前缀的属性换为新的重命名属性,因此若是你在目前的代码中使用兼容性更好的老名字也不用担忧。

重命名意味着这些属性也能被应用于其余布局方法,一个明显的备选就是弹性盒子。虽然目前没有浏览器支持盒子模型中的gap属性,可是在将来咱们应该可使用column-gaprow-gap来建立弹性项目元素间的间距。

8.2. 关于box generation的其余阅读资料


9. 多栏布局(多列布局)

多栏布局(multi-column layout)是一种支持建立多栏的布局类型,如同报纸上那样。每一块都被分割成栏(column),你会按照块方向在栏中往下读而后会在回到下一栏的顶部。然而用这种方式阅读在网页内容中并不老是有效,由于人们并不想去让滚动条滚动来、滚动去地去阅读。当须要展现少部份内容、折叠一组复选框或者其余一些小的UI组件时会很是有用。

当展现一组高度不一样的卡片或产品时多栏布局也很是有用。

9.1. 设置栏的宽度

要设置一个最有的栏宽,并通知浏览器依此宽度展现尽量多的栏可使用下面的CSS:

.container {
    column-width: 300px;
}
复制代码

这会建立尽量多的300px的栏,全部剩下的空间会被全部栏共享。所以,除非空间被划分为300px时没有剩余,不然你的栏会比300px稍多一些。

9.2. 设置栏的数目

除了设置宽度,你可使用column-count来设置栏的数目。在这种状况下,浏览器会将空间均分给你须要的数目的栏。

.container {
    column-count: 3;
}
复制代码

若是你同时添加了column-widthcolumn-count,那么column-count属性会做为一个最大值限制。在下面的代码里,栏会被添加直到达到三个,此时任何额外的空间都会被分给三栏,即便空间足够成为一个额外的新栏。

.container {
    column-width: 300px;
    column-count: 3;
}
复制代码

9.3. 间距和栏规则

你没法为单个栏盒子添加外边距和内边距,须要用column-gap属性来设置间距。若是你不具体指定column-gap的值,它会默认为1em来防止栏间碰撞。这和其余布局方法中column-gap的行为不同,其余布局中默认为0。你能够在间距上使用任意的长度单元,包括0(若是你不但愿有栏间距)。

column-rule属性让你有能力向两栏间添加规则。它是column-rule-widthcolumn-rule-colorcolumn-rule-style的简写形式,可border行为相似。注意,一个规则自身不会占用任何空间。它会占据在间距的顶部,从而增长或减小那些你设置column-gap的规则与内容间的空间。

<div class="container">
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  column-width: 120px;
  column-gap: 20px;
  column-rule: 4px dotted #000;
}
复制代码

example: Smashing Guide to Layout: multicol on Codepen

9.4. 容许元素横跨多栏

你可使用column-span属性让多栏容器内的元素横跨多栏,相似通栏。

h3 {
    column-span: all;
}
复制代码

column-span出现时,多栏容器分栏会在这个元素上放停下,所以,容器里的内容会在元素上方造成多栏样式,而后在横跨元素(spanning element)的下方造成一组新的栏盒子(column box)。

<div class="container">
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  <h2>Veggies!</h2>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. </p>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  column-width: 120px;
  column-gap: 20px;
  column-rule: 4px dotted #000;
}

.container h2 {
  column-span: all;
  background-color: rgba(193,225,237,.6);
  border:2px solid rgba(193,225,237,.6);
  margin: 1em 0;
  padding: .5em;
}
复制代码

example: Smashing Guide to Layout: multicol span on Codepen

你只可使用column-span: allcolumn-span: none,并不能让元素横跨某几个栏(非通栏)。在文章写做时,Firefox还不支持column-span属性。

9.5. 关于多栏布局的其余阅读资料


10. 碎片化(Fragmentation)

多栏布局是碎片化(fragmentation)的一个例子,页面内容会被拆分红栏。这和打印时内容被分到不一样页很是相似。这个过程是碎片化规范(Fragmentation specification)处理的。这个规范包括了一些帮助控制内容切分的属性。

例如,若是你有一组置于多栏中的卡片,而且你想确保卡片不会被截为两半分到不一样的栏,你可使用break-inside属性的avoid值。考虑浏览器兼容性的因素,你也可能会想使用遗留的page-break-inside属性。

.card {
    page-break-inside: avoid;
    break-inside: avoid;
}
复制代码

若是你想在heading元素后禁止断行,你可使用break-after属性。

.container h2 {
    page-break-after: avoid;
    break-after: avoid;
}
复制代码

这些属性能够被用在打印样式或多栏样式中。在下面的例子里,在多栏容器中的三个段落被拆分到了三栏之中。我为p元素设置了break-inside: avoid,这意味着每一个多栏会在本身的栏中结束(即便这会使各栏长度不一样)。

<div class="container">
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout</p>
  
  <p>Groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
复制代码
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  column-width: 120px;
  column-gap: 20px;
  column-rule: 4px dotted #000;
}

.container p {
  page-break-inside: avoid;
  break-inside: avoid;
}
复制代码

example: Smashing Guide to Layout: multicol fragmentation on Codepen

10.1. 关于碎片化的其余阅读资料


11. 如何选择布局类型?

大多数的网页会混合使用多种布局类型。各布局规范都准肯定义了它们之间是如何相互做用的。例如,你可能会在网格布局的网格项中使用弹性布局。一些弹性容器可能具备定位属性或浮动。这些规范根据最优的布局方式已经包含了布局模型的混合使用。在这篇指南中,我尝试概述了这种布局类型的基本使用方式,来帮助你了解实现一个效果可能的最好方法。

然而,别惧怕去运用多种方式来实现布局设计。担忧你的选择会不会形成实际问题的状况比你想象中要少不少。因此请在开始就组织好你的文档结构,而且注意你文档内容的可视展现顺序。剩下的大部分工做就是在浏览器中试试你的布局方式是否符合预期。


原文:Getting Started With CSS Layout,感谢做者Rachel Andrew。

相关文章
相关标签/搜索