本篇文章的内容基本来自《学习CSS布局》教程,如有疑问可直接去教程官网去查看,本篇文章只做精炼提取。
一、知识点
- 每一个元素都有默认的
display
属性,如block、inline、none等 - 块级元素的
width
元素可以防止它撑满整个屏幕 - 设置块级元素的宽度之后,再设置其左右外边距为
auto
则可以让其居中显示 - 所有浏览器都支持
max-width
属性
二、盒模型
讨论宽度的时候,应该结合另外一个相关联的重要的知识点:盒模型
。
当你设置了元素的宽度,实际展现的元素却超出你的设置:这是因为元素的边框和内边距会撑开元素。
.simple {
width: 500px;
margin: 20px auto;
}
.fancy {
width: 500px;
margin: 20px auto;
padding: 50px;
border-width: 10px;
}
人们慢慢的意识到传统的盒子模型不直接,所以他们新增了一个叫做 box-sizing
的CSS属性。当你设置一个元素为 box-sizing: border-box;
时,此元素的内边距和边框不再会增加它的宽度。如下:
.simple {
width: 500px;
margin: 20px auto;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.fancy {
width: 500px;
margin: 20px auto;
padding: 50px;
border: solid blue 10px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
既然没有比这更好的方法,一些CSS开发者想要页面上所有的元素都有如此表现。所以开发者们把以下CSS代码放在他们页面上:
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
这样可以确保所有的元素都会用这种更直观的方式排版。
不过 box-sizing
是个很新的属性,目前你还应该像我上面例子中那样使用 -webkit-
和 -moz-
前缀。这可以启用特定浏览器实验中的特性。同时记住它是支持IE8+的。
结论
box-sizing: border-box;
属性会使元素的内边距和边框不再会增加它的宽度
三、Position 定位
更多复杂的布局,需要使用 position
属性。
它有一大堆的值,名字还都特抽象,very 难记。
我们一个个的过一遍,不过最好还是把这页放到书签里。
3.1 static
.static {
position: static;
}
static 是默认值。任意
position: static;
的元素不会被特殊的定位。一个 static
元素表示它不会被“positioned”,一个 position
属性被设置为其他值的元素表示它会被“positioned”。
3.2 relative
.relative1 {
position: relative;
}
.relative2 {
position: relative;
top: -20px;
left: 20px;
background-color: white;
width: 500px;
}
relative 表现的和 static 一样,除非你添加了一些额外的属性。
在一个相对定位(position属性的值为relative)的元素上设置 top 、 right 、 bottom 和 left 属性会使其偏离其正常位置。其他的元素的位置则不会受该元素的影响发生位置改变来弥补它偏离后剩下的空隙。
3.3 fixed
一个固定定位(position属性的值为fixed)元素会相对于视窗来定位,这意味着即便页面滚动,它还是会停留在相同的位置。和 relative 一样, top 、 right 、 bottom 和 left 属性都可用。
.fixed {
position: fixed;
bottom: 0;
right: 0;
width: 200px;
background-color: white;
}
以上的代码,会让一个元素固定在浏览器右下角。
一个固定定位元素不会保留它原本在页面应有的空隙(脱离文档流)。
令人惊讶地是移动浏览器对 fixed 的支持很差。这里有相应的解决方案.
3.4 absolute
absolute
是最棘手的 position
值。 absolute
与 fixed
的表现类似,但是它不是相对于 视窗
而是相对于最近的“positioned”祖先元素。如果绝对定位(position属性的值为absolute)的元素没有“positioned”祖先元素,那么它是相对于文档的 body 元素,并且它会随着页面滚动而移动。
记住一个“positioned”元素是指 position 值不是 static 的元素。
这里有一个简单的例子:
.relative {
position: relative;
width: 600px;
height: 400px;
}
.absolute {
position: absolute;
top: 120px;
right: 0;
width: 300px;
height: 200px;
}
这部分比较难理解,但它是创造优秀布局所必需的知识。下面我们会使用 position 做更具体的例子。
3.5 position例子
通过具体的例子可以帮助我们更好地理解“position”。下面是一个真正的页面布局。
.container {
position: relative;
}
nav {
position: absolute;
left: 0px;
width: 200px;
}
section {
/* position is static by default */
margin-left: 200px;
}
footer {
position: fixed;
bottom: 0;
left: 0;
height: 70px;
background-color: white;
width: 100%;
}
body {
margin-bottom: 120px;
}
这个例子在容器比nav元素高的时候可以正常工作。如果容器比nav元素低,那么nav会溢出到容器的外面。之后我们会讨论下其他布局技术,它们都各有优劣。
四、float 浮动
另一个布局中常用的CSS属性是 float 。Float 可用于实现文字环绕图片,如下:
img {
float: right;
margin: 0 0 1em 1em;
}
4.1 clear 控制浮动
clear 属性被用于控制浮动。比较下面两个例子:
<div class="box">...</div>
<section>...</section>
.box {
float: left;
width: 200px;
height: 100px;
margin: 1em;
}
在这个例子中, section 元素实际上是在 div 之后的(译注:DOM结构上)。然而 div 元素是浮动到左边的,于是 section 中的文字就围绕了 div ,并且 section 元素包围了整个元素。如果我们想让 section 显示在浮动元素之后呢?
.box {
float: left;
width: 200px;
height: 100px;
margin: 1em;
}
.after-box {
clear: left;
}
使用
clear
我们就可以将这个段落移动到浮动元素 div 下面。你需要用 left
值才能清除元素的向左浮动。你还可以用 right
或 both
来清除向右浮动或同时清除向左向右浮动。
4.2 overflow 清除浮动(clearfix hack)
在使用浮动的时候经常会遇到一个古怪的事情:
img {
float: right;
}
这个图片比包含它的元素还高, 而且它是浮动的,于是它就溢出到了容器外面!
见证奇迹的时刻到了!有一种比较丑陋的方法可以解决这个问题,它叫做清除浮动(clearfix hack).
让我们加入一些新的CSS样式:
.clearfix {
overflow: auto;
}
现在再看看发生了什么:
这个可以在现代浏览器上工作。如果你想要支持IE6,你就需要再加入如下样式:
.clearfix {
overflow: auto;
zoom: 1;
}
有些独特的浏览器需要“额外的关照”。清除浮动这潭水很深很深,但是这个简单的解决方案已经可以在今天所有的主要浏览器上工作。
4.3 浮动布局例子
完全使用 float
来实现页面的布局是很常见的。这里有一个我之前用 position
实现的布局例子,这次我使用 float 实现了它。
nav {
float: left;
width: 200px;
}
section {
margin-left: 200px;
}
这个例子和之前那个外观一模一样。请注意我们在容器上做了“清除浮动”。原本在这个例子中是不需要的,但是当 nav 比非浮动的内容还要高时就需要了。
4.4 百分比宽度
百分比是一种相对于包含块的计量单位。它对图片很有用:如下我们实现了图片宽度始终是容器宽度的50%。把页面缩小看下效果!
你甚至还能同时使用 min-width 和 max-width 来限制图片的最大或最小宽度!
4.5 百分比宽度布局
你可以用百分比做布局,但是这需要更多的工作。在下面的例子中,当窗口宽度很窄时 nav 的内容会以一种不太友好的方式被包裹起来。总而言之,选一种最合适你的内容的方式。
nav {
float: left;
width: 25%;
}
section {
margin-left: 25%;
}
当布局很窄时, nav 就会被挤扁。更糟糕的是,你不能在 nav 上使用 min-width 来修复这个问题,因为右边的那列是不会遵守它的。
4.6 媒体查询
“响应式设计(Responsive Design” 是一种让网站针对不同的浏览器和设备“呈现”不同显示效果的策略,这样可以让网站在任何情况下显示的很棒!
媒体查询是做此事所需的最强大的工具。让我们使用百分比宽度来布局,然后在浏览器变窄到无法容纳侧边栏中的菜单时,把布局显示成一列:
@media screen and (min-width:600px) {
nav {
float: left;
width: 25%;
}
section {
margin-left: 25%;
}
}
@media screen and (max-width:599px) {
nav li {
display: inline;
}
}
当你调整浏览器窗口大小时,布局比以前更酷了!
现在我们的布局在移动浏览器上也显示的很棒。这里有一些同样使用了媒体查询的著名站点。在MDN文档中你还可以学到更多有关媒体查询的知识。
额外加分点
使用 meta viewport 之后可以让你的布局在移动浏览器上显示的更好。
4.7 inline-block
你可以创建很多网格来铺满浏览器。在过去很长的一段时间内使用 float 是一种选择,但是使用 inline-block 会更简单。让我们看下使用这两种方法的例子:
4.7.1 困难的方式(使用浮动)
.box {
float: left;
width: 200px;
height: 100px;
margin: 1em;
}
.after-box {
clear: left;
}
由于
.after-box
使用了 clear: left
,所以黄色的div没有浮动到上面的那堆盒子旁边
4.7.2容易的方式(使用 inline-block)
你可以用 display 属性的值 inline-block 来实现相同效果。
你得做些额外工作来让IE6和IE7支持
inline-block
。有些时候人们谈到 inline-block
会触发叫做 hasLayout
的东西,你只需要知道那是用来支持旧浏览器的。如果你对此很感兴趣,可以在前面那个链接中找到更详细的信息。否则我们就继续下去吧。
4.8 inline-block 布局
你可以使用 inline-block 来布局。有一些事情需要你牢记:
- vertical-align 属性会影响到 inline-block 元素,你可能会把它的值设置为 top 。
- 你需要设置每一列的宽度
- 如果HTML源代码中元素之间有空格,那么列与列之间会产生空隙局
nav {
display: inline-block;
vertical-align: top;
width: 25%;
}
.column {
display: inline-block;
vertical-align: top;
width: 75%;
}
五、CSS新属性column
这里有一系列新的CSS属性,可以帮助你很轻松的实现文字的多列布局。让我们瞧瞧:
.three-column {
padding: 1em;
-moz-column-count: 3;
-moz-column-gap: 1em;
-webkit-column-count: 3;
-webkit-column-gap: 1em;
column-count: 3;
column-gap: 1em;
}
CSS columns是很新的标准,所以你需要使用前缀,并且它不被IE9及以下和Opera Mini支持。还有许多和 column 相关的属性,点击这里了解更多。否则让我们讨论下一个主题。
六、 flexbox布局
新的 flexbox
布局模式被用来重新定义CSS中的布局方式。很遗憾的是最近规范变动过多,导致各个浏览器对它的实现也有所不同。不过我仍旧想要分享一些例子,来让你知道即将发生的改变。这些例子目前只能在支持 flexbox 的 Chrome 浏览器中运行,基于最新的标准。
网上有不少过时的 flexbox 资料。 如果你想要了解更多有关 flexbox 的内容,从这里学习如何辨别一份资料是否过时。我已经写了一份关于最新标准的详细文章。
使用flexbox你还可以做的更多;这里只是一些让你了解概念的例子:
使用 Flexbox 的简单布局
.container {
display: -webkit-flex;
display: flex;
}
nav {
width: 200px;
}
.flex-column {
-webkit-flex: 1;
flex: 1;
}
使用 Flexbox 的牛逼布局
.container {
display: -webkit-flex;
display: flex;
}
.initial {
-webkit-flex: initial;
flex: initial;
width: 200px;
min-width: 100px;
}
.none {
-webkit-flex: none;
flex: none;
width: 200px;
}
.flex1 {
-webkit-flex: 1;
flex: 1;
}
.flex2 {
-webkit-flex: 2;
flex: 2;
}
使用 Flexbox 的居中布局
.vertical-container {
height: 300px;
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
-webkit-justify-content: center;
justify-content: center;
}