界面设计技法之css布局(纯干货)


css布局之于页面就如同ECMAScript之于JS一般,细想一番,html就如同语文,css就如同数学,js呢,就是物理,有些扯远,这里就先不展开了。 回到主题,从最开始的css到如今的sass(less),开发的效率确实变得越来越高效,但是可能有时候我们还是会对页面布局产生烦恼的情绪,比如:"咦?我想让它显示在这个部位,它一点都不听话啊"。很大原因在于我们可能没对css布局这块做一个系统的梳理~,偶然间发现了Learn CSS Layout,在此分享给大家,希望和大家共同提高,另外安利给大家一个如何写出更加优雅的html&&css代码的文章,使劲戳我!

填坑"display"

display 是CSS中最重要的用于控制布局的属性。每个元素都有一个默认的 display 值,这与元素的类型有关。对于大多数元素它们的默认值通常是 block 或 inline 。一个 block 元素通常被叫做块级元素。一个 inline 元素通常被叫做行内元素。

block:

div 是一个标准的块级元素。一个块级元素会新开始一行并且尽可能撑满容器。其他常用的块级元素包括 p 、 form 和HTML5中的新元素: header 、 footer 、 section 等等。
 
inline:
span 是一个标准的行内元素。一个行内元素可以在段落中<span> 像这样 </span>包裹一些文字而不会打乱段落的布局。 a 元素是最常用的行内元素,它可以被用作链接。
 
none:

另一个常用的display值是 none 。一些特殊元素的默认 display 值是它,例如 script。 display:none 通常被 JavaScript 用来在不删除元素的情况下隐藏或显示元素。

它和 visibility 属性不一样。把 display 设置成 none 不会保留元素本该显示的空间,但是 visibility: hidden; 还会保留。

扩展:

每个元素都有一个默认的 display 类型。不过你可以随时随地的重写它!常见的例子是:把 li 元素修改成 inline,制作成水平菜单。

*inline-block布局

把inline-block单独拎出来讲,说来惭愧,很长一段时间我都是蒙着用它的,对于block、inline、inline-block的区别我自己总结了一句话

block:有宽高,不在同一行;
inline:同一行,无宽高;
inline-block: 有宽高又在同一行

这算是个小插曲吧,接着我们的布局之旅;在此之前,读者需可以先阅读下文的float布局和clear的知识再回头来看这知识会容易不少,然后我们会对比inline-block布局相对于float布局的优势;

困难的方式(float布局)

.box {
  float: left;
  width: 200px;
  height: 100px;
  margin: 1em;
}
.after-box {
  clear: left;
}

.box 我在浮动

.box 我在浮动

.box 我在浮动

.box 我在浮动

.box 我在浮动

.box 我在浮动

.box 我在浮动

.box 我在浮动

.box 我在浮动

.box 我在浮动

.box 我在浮动

.after-box 我在使用 clear,所以我不会浮动到上面那堆盒子的旁边。 

容易的方式(使用inline-block)

你可以用 display 属性的值 inline-block 来实现相同效果。  

.box2 {
  display: inline-block;
  width: 200px;
  height: 100px;
  margin: 1em;
}

.box2 我是一个行内块!

.box2 我是一个行内块!

.box2 我是一个行内块!

.box2 我是一个行内块!

.box2 我是一个行内块!

.box2 我是一个行内块!

.box2 我是一个行内块!

.box2 我是一个行内块!

.box2 我是一个行内块!

.box2 我是一个行内块!

.box2 我是一个行内块!

这次我可没有用 clear 。太棒了!

使用inline-block布局的注意项:

①vertical-align 属性会影响到 inline-block 元素,你可能会把它的值设置为 top 。
②你需要设置每一列的宽度
③如果HTML源代码中元素之间有空格,那么列与列之间会产生空隙

 

你得做些额外工作来让IE6和IE7支持 inline-block 。有些时候人们谈到 inline-block 会触发叫做 hasLayout 的东西,你只需要知道那是用来支持旧浏览器的。如果你对此很感兴趣,可以在后面的链接中找到更详细的信息。

margin:auto&&max-width

margin:auto:

#main {
  width: 600px;
  margin: 0 auto; 
}

设置块级元素的 width 可以阻止它从左到右撑满容器。然后你就可以设置左右外边距为 auto 来使其水平居中。元素会占据你所指定的宽度,然后剩余的宽度会一分为二成为左右外边距。

唯一的问题是,当浏览器窗口比元素的宽度还要窄时,浏览器会显示一个水平滚动条来容纳页面。让我们再来改进下这个方案...

max-width:

#main {
  max-width: 600px;
  margin: 0 auto; 
}

在这种情况下使用 max-width 替代 width 可以使浏览器更好地处理小窗口的情况。这点在移动设备上显得尤为重要,调整下浏览器窗口大小检查下吧!

顺便提下, 所有的主流浏览器包括IE7+在内都支持 max-width ,所以放心大胆的用吧。

盒模型

在我们讨论宽度的时候,我们应该讲下与它相关的一个重点知识:盒模型。当你设置了元素的宽度,实际展现的元素却能够超出你的设置:因为元素的边框和内边距会撑开元素。看下面的例子,两个相同宽度的元素显示的实际宽度却不一样。

.simple {
  width: 500px;
  margin: 20px auto;
}

.fancy {
  width: 500px;
  margin: 20px auto;
  padding: 50px;
  border: 10px #6AC5AC solid;
}

class="simple":

我小一些...

class="fancy":

 我比它大!

以前有一个代代相传的解决方案是数学。CSS开发者需要用比他们实际想要的宽度小一点的宽度,需要减去内边距和边框的宽度。值得庆幸地是你不需要再这么做了,让我们接着看...

※box-sizing※

这个部分是我着重向大家分享的知识点,因为自己以前没掌握o(╯□╰)o,推荐大家多用用box-sizing属性;

经过了一代又一代人们意识到数学不好玩,所以他们新增了一个叫做 box-sizing 的CSS属性。当你设置一个元素为 box-sizing: border-box; 时,此元素的内边距和边框不再会增加它的宽度。这里有一个与前一页相同的例子,唯一的区别是两个元素都设置了 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: 10px #6AC5AC solid;
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
}

class="simple":

我们现在一样大小了! 

class="fancy": 

 万岁!

既然没有比这更好的方法,一些CSS开发者想要页面上所有的元素都有如此表现。所以开发者们把以下CSS代码放在他们页面上: 

* {
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
}

既然 box-sizing 是个很新的属性,目前你还应该像我之前在例子中那样使用 -webkit- 和 -moz- 前缀。这可以启用特定浏览器实验中的特性。同时记住它是支持IE8+。

position布局

为了制作更多复杂的布局,我们需要讨论下 position 属性。它有一大堆的值,名字还都特抽象,别提有多难记了。让我们先一个个的过一遍,不过你最好还是把这页放到书签里。

static:

.static {
  position: static;
}

 static 是默认值。任意 position: static; 的元素不会被特殊的定位。一个 static 元素表示它不会被“positioned”,一个 position 属性被设置为其他值的元素表示它会被“positioned”。

relative: 

relative是我项目里用到的最多的属性了,它通常和绝对定位相结合;

.relative1 {
  position: relative;
}
.relative2 {
  position: relative;
  top: -20px;
  left: 20px;
  width: 500px;
}

relative1 表现的和 static 一样,除非你添加了一些额外的属性。 

在一个相对定位(position属性的值为relative)的元素上设置 top、 right 、 bottom 和 left 属性会使其偏离其正常位置。其他的元素则不会调整位置来弥补它偏离后剩下的空隙。

fixed:

一个固定定位(position属性的值为fixed)元素会相对于视窗来定位,这意味着即便页面滚动,它还是会停留在相同的位置。和 relative 一样, top 、 right 、 bottom和 left 属性都可用。

一个固定定位元素不会保留它原本在页面应有的空隙。

令人惊讶地是移动浏览器对 fixed 的支持很差。这里有相应的解决方案.

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: static; ,那么它的绝对定位子元素会跳过它直接相对于body元素定位。

 

 

这个元素是绝对定位的。它相对于它的父元素定位。

给想练手的新同学留个小作业吧,用relative+absolute实现出下面这个简单的登录Demo,后期贴上源码;

以上这部分可能有些难理解,但它是创造优秀布局所必需的知识。

float布局

另一个布局中常用的CSS属性是 float 。Float 可用于实现文字环绕图片,如下:

img {
  float: right;
  margin: 0 0 1em 1em;
}

 

An Image

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas odio, vitae scelerisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Mauris ante ligula, facilisis sed ornare eu, lobortis in odio. Praesent convallis urna a lacus interdum ut hendrerit risus congue. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta. Cras ac leo purus. Mauris quis diam velit.

 *clear

clear 属性被用于控制浮动。比较下面两个例子:(貌似博客园不支持<section>标签,代码里我用<div>代替,大家懂意思就行)

<div class="box">我感觉好像我在漂浮!</div>
<section> 在这个例子中, section 元素实际上是在 div 之后的(译注:DOM结构上)。然而 div 元素是浮动到左边的,于是 section 中的文字就围绕了 div ,并且 section 元素包围了整个元素。如果我们想让 section 显示在浮动元素之后呢?</section>
.box {
  float: left;
  width: 200px;
  height: 100px;
  margin: 1em;
}

div class="box" 我感觉好像我在漂浮!

section  在这个例子中, section 元素实际上是在 div 之后的(译注:DOM结构上)。然而 div 元素是浮动到左边的,于是 section 中的文字就围绕了 div ,并且 section 元素包围了整个元素。如果我们想让 section 显示在浮动元素之后呢?

 

  

.box {
  float: left;
  width: 200px;
  height: 100px;
  margin: 1em;
}
.after-box {
  clear: left;
}

div class="box" 我感觉好像我在漂浮!

section class="after-box" 使用 clear 我们就可以将这个段落移动到浮动元素 div 下面。你需要用 left 值才能清除元素的向左浮动。你还可以用 right 或 both 来清除向右浮动或同时清除向左向右浮动。

 *清除浮动(clearfix hack)
img {
  float: right;
}
An Image

不......这个图片比包含它的元素还高, 而且它是浮动的,于是它就溢出到了容器外面!

 

见证奇迹的时刻到了!有一种比较丑陋的方法可以解决这个问题,它叫做清除浮动(clearfix hack).

让我们加入一些新的CSS样式:

.clearfix {
  overflow: auto;
}

现在再看看发生了什么:

An Image

<div class="clearfix"> 好多了!

 这个可以在现代浏览器上工作。如果你想要支持IE6,你就需要再加入如下样式:

.clearfix {
  overflow: auto;
  zoom: 1;
}

有些独特的浏览器需要“额外的关照”。清除浮动这谭水很深很深,但是这个简单的解决方案已经可以在今天所有的主要浏览器上工作。

百分比宽度布局

百分比是一种相对于包含块的计量单位。它对图片很有用:如下我们实现了图片宽度始终是容器宽度的50%。把页面缩小看下效果!

article img {
  float: right;
  width: 50%;
}
An Image

你甚至还能同时使用 min-width 和 max-width 来限制图片的最大或最小宽度!

你可以用百分比做布局,但是这需要更多的工作。总而言之,选一种最合适你的内容的方式。附上之前做的一个用百分比做布局的项目。

这是微信端的展示,从中我们可以看出如果用百分比布局来做界面比较明朗的界面的话,那在兼容多种终端上,它能帮我们省下不少力气,另外该项目已经开源,喜欢的朋友可以去star一下哟;项目地址

媒体查询

“响应式设计(Responsive Design)”是一种让网站针对不同的浏览器和设备“响应”不同显示效果的策略,这样可以让网站在任何情况下显示的很棒!

媒体查询是做此事所需的最强大的工具。

现在我们的布局在移动浏览器上也显示的很棒。这里有一些同样使用了媒体查询的著名站点。在MDN文档中你还可以学到更多有关媒体查询的知识。

demo
@media screen and (min-width:640px) {
  ...  
}
@media screen and (max-width:768px) {
  ...  
}

补充:使用 meta viewport 之后可以让你的布局在移动浏览器上显示的更好。

使用方法:<meta name=”viewport” content=”” />

在实际项目中,为了让Responsive设计在智能设备中能显示正常,也就是浏览Web页面适应屏幕的大小,显示在屏幕上,可以通过这个可视区域的meta标签进行重置,告诉他使用设备的宽度为视图的宽度,也就是说禁止其默认的自适应页面的效果,具体设置如下:

<meta name=”viewport” content=”width=device-width,initial-scale=1.0” />
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;
}

为了能在Web页面中方便实现类似报纸、杂志那种多列排版的布局,W3C特意给CSS3增加了一个多列布局模块(CSS Multi Column Layout Module)。它主要应用在文本的多列布局方面,这种布局在报纸和杂志上都使用了几十年了,但要在Web页面上实现这样的效果还是有相当大的难度,为此W3C特意给CSS3增加了一个多列布局模块(CSS Multi Column Layout Module)。

CSS columns是很新的标准,所以你需要使用前缀,并且它不被IE9及以下和Opera Mini支持。还有许多和 column 相关的属性,点击这里了解更多。 

flexbox布局

新的 flexbox 布局模式被用来重新定义CSS中的布局方式。很遗憾的是最近规范变动过多,导致各个浏览器对它的实现也有所不同。这次分享一些例子,来让你知道即将发生的改变。这些例子目前只能在支持 flexbox 的 Chrome 浏览器中运行,基于最新的标准。

网上有不少过时的 flexbox 资料。 如果你想要了解更多有关 flexbox 的内容,从这里学习如何辨别一份资料是否过时。或者查看关于最新标准的详细文章。 

使用flexbox你还可以做的更多;这里只是一些让你了解概念的例子:

使用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;
}

.initial 空间足够的时候,我的宽度是200px,如果空间不足,我会变窄到100px,但不会再窄了。

.none 无论窗口如何变化,我的宽度一直是200px。

.flex1 剩余宽度的1/3。

.flex2 我会占满剩余宽度的2/3。

使用Flexbox的居中布局

.vertical-container {
  height: 300px;
  display: -webkit-flex;
  display:         flex;
  -webkit-align-items: center;
          align-items: center;
  -webkit-justify-content: center;
          justify-content: center;
}
 CSS里总算是有了一种简单的垂直居中布局的方法了!
写在最后

再次感谢Learn CSS Layout 的作者,给我们带来了如此绝妙的css布局盛宴,同时也感谢敏明君和sunnylost的翻译,在以上前辈力作的基础上,云云加了不少个人观点,如有不当,还请博友们指出。原作是如此优秀,忍不住让云云连续花了6个多小时,整理并手敲实现了每行样式代码。真心建议有时间的朋友能好好阅读下原文以及其中诸多的超棒的链接,不管对知识的巩固亦或是进阶一定大有裨益!最后,十分感谢朋友们的阅读,望与大家共同提高!