CSS 布局

将元素以正确的大小摆放在正确的位置上;元素摆放的模式;

即,CSS 中影响元素大小和位置的因素;元素摆放的模式。

怎么理解呢?网页布局的核心,就是用 CSS 来摆放盒子位置。那么,如何把盒子摆放到合适的位置呢?

在 CSS 中有 3 种元素摆放的模式:标准文档流、浮动和定位。


[ 标准文档流(Normal Flow)]                                  { 视觉格式化?↓ }

~,又称普通流或文档流,实际上就是网页内标签元素正常从上到下、从左到右顺序排列的意思。如块级元素会独占一行,行级元素会按序依次前后排列,按这种大前提的布局排列之下绝对不会出现例外的情况,就叫做标准文档流布局。

简单讲就是,从上到下,从左到右的输出文档内容;它由块级元素和行级元素组成,且它们都是盒子模型。

// 下面为 Firefox 布局可视化 Gecko Reflow Visualisation。


display 设置元素的显示方式

在 HTML 中,标签一般分为块级标签和行级标签,又称为块级元素和行级元素。

  • 块级元素:通常都会独占一行,可以对齐设置宽高、对齐等属性,常用于网页布局和网页结构的搭建。
  • 行级元素:不占有独立的区域,仅仅靠自身的字体大小和图片尺寸来支持结构,一般不可以设置宽高、对齐等属性,常用于控制页面中文本的样式。        // 水平方向的padding和margin可以设置,但垂直方向的无效。
  • 行级元素中有几个特殊的标签img、input、td等,对它们可以设置宽高和对齐属性,称之为行级块状标签。其特点为:和相邻行内块在一行上,但之间会有空白间隙;默认宽度为内容宽度,可设置宽高和内外边距。

display:block | inline | inline-block | none

注,默认宽度和设置宽高,影响元素大小;起始位置,影响元素位置。
默认:
  display:block(块级元素)    div,p,h1~h6,ul,form…;div是最典型的块级元素。
  display:inline(行级元素)    span,a,label,cite,em…;span是最典型的行级元素。
  display:inline-block     input,textarea,select,button…
  display:none(设置元素不显示,不占空间)  VS  visibility:hidden(不显示,隐藏,但占空间)

注,块级元素可以容纳行级元素和其他块级元素;行级元素只能容纳文本或其他行级元素(a除外)。


[ display?↓ 的应用 ]                           { 元素显示、隐藏的9种方式?↓ }

  • 模式A:块级元素水平居中
HTML    <div>
            <div class=”content”>content area</div>
        </div>
CSS     .content{width:300px;height:300px;background-color:pink;}
        .content{margin:0 auto;}
  • 模式B:居中导航
HTML    <ul class=”m-nav”>
            <li><a href=”#”>推荐</a></li>
            <li><a href=”#”>歌单</a></li>
            <li class=”cur”><a href=”#”>主题</a></li>
         </ul>
CSS      ul{text-align:center;height:30px;line-height:30px;background-color:#f00;}
         li,a{display:inline-block;width:80px;height:100%;}
         li{margin:0 5px;list-style:none;}
         a,a:hover,li.cur a{color:#fff;text-decoration:none;}
         a:hover,li.cur a{background-color:#c00;}

float 浮动 - 块级元素同行显示,在文档流(半脱离文档流)

[ 浮动的由来 ]浮动最早是用来控制图片的,以便达到其他元素(特别是文字)实现“环绕”图片的效果。

后来,大家发现浮动有个非常有意思的特性,就是可以让任何盒子在同一行中排列。换句话来说就是,浮动可以使得块级元素同行显示,因此,浮动被逐渐应用到网页布局当中。

[1] 浮动,是指设置了浮动属性的元素会脱离普通文档流的控制,移动到其父元素中指定位置的过程。

其主要目的是为了让多个块级元素在同一行内显示。                               { 深入了解float?↓ }

float:left | right | none | inherit

   left:元素向左移动;
   right:元素向右移动;
   none:元素不浮动(默认值);

[ 特性一 ] 文档流(“漂浮起来”)/ 默认宽度为内容宽度(可设置宽高)/ 向指定方向一直移动(只有左右浮动)

[ 特性二 ] float 的元素在同一文档流

[ 特性三 ] float 元素半脱离文档流( 对后续元素,脱离文档流;对内容,在文档流)                    // BFC用途?!


浮动创建包含块的概念(包裹),也就是说,浮动的元素总是找离它最近的父元素对齐,但不会超出内边距范围。

因此,从布局的稳定性考虑,浮动首先需要添加标准流父级。

[ 排列规则 ] 浮动元素A的排列位置,跟上一个元素(块级)有关系。如果上一个元素有浮动,则 A 元素顶部会和上一个元素的顶部对齐;如果上一个元素是标准流,则 A 元素的顶部会和上一个元素的底部对齐。

[ 显示模式 ] 添加浮动后,元素会具有行级块状元素的特性,元素的大小取决于定义的大小或默认内容的多少。


[2] 清除浮动,本质上来讲,主要是为了解决父元素因为子元素浮动引起内部高度为 0 的问题。

很多时候,我们不方便给定父元素高度,比如新闻,因为你不知道新闻里面会有多少字,一般是让内容自动撑开。

在CSS中,clear属性用于清除浮动,其基本语法为:
   clear:both | left | right | none | inherit           应用于后续元素&块状元素

   // 清除浮动的隐藏方式:给父元素设定固定高度。

[ 清除浮动的方式 ]  “闭合”思想:把浮动的盒子圈在里面,让父盒子闭合出口和入口,不让子盒子出来影响其他元素。

  • 空白元素:W3C 推荐,在浮动元素末尾添加一个空白标签
<div class="parent">
    <div class="sample">float:left</div>
    <div class="sample">float:left</div>
    <br class="cb">
</div> 
.sample{float:left;}
.cb{clear:both;height:0;overflow:hidden;visibility:hidden;}

优点:通俗易懂,书写方便
缺点:添加许多无意义的标签,结构化较差。不建议使用。
  • 父级添加 overflow 方法:可以通过出发BFC?!的方式,可以实现清除浮动效果。
给父级添加:overflow 为 hidden | auto | scroll 都可以实现

优点:代码简洁
缺点:内容增多时候容易发生内容不会自动换行而导致内容被隐藏,无法显示需要溢出的元素。
  • clearfix — after 伪元素清除浮动
<div class="sc clearfix">
    <div class="sample">float:left</div>
</div>
.clearfix:after{
    content:".";display:block;clear:both;
    height:0;overflow:hidden;visibility:hidden;
}
.clearfix{zoom:1;}  // IE低版本不支持after,加上这个

优点:结构语义化正确
缺点:IE6-7不支持:after,使用zoom:1出发hasLayout,代表网站:百度、淘宝、网易等,推荐使用。
  • clear fix  — 双伪元素清除浮动
.clearfix:before,.clearfix:after{
    content:".";
    display:table;
}
.clearfix:after{ clear:both; }
.clearfix{ zoom:1 }

优点:代码更简洁
缺点:由于IE6-7不支持:after,使用zoom:1出发hasLayout,代表网站:小米、腾讯等,推荐使用。

position 设置定位方式(参照物)

[ 为什么学习定位 ] 从下图( // 在新标签页打开图像 )中发现定位的常见应用场景:

XXXXX ,如果用标准流或浮动,实现起来会比较复杂或难以实现,此时就需要使用定位来做。


元素的定位属性主要包括定位模式和边偏移两个部分。

[1] 边偏移(设置位置):top、right、bottom、left、z-index

其用于设置元素边缘与参照物边缘的距离,且设置的值可为负值。在同时设置相对方向时,元素将被拉伸。

  top               顶端偏移量。定义元素相对于其父元素上边线的距离。
  bottom            底部偏移量。定义元素相对于其父元素下边线的距离。
  left              左侧偏移量。定义元素相对于其父元素左边线的距离。
  right             右侧偏移量。定义元素相对于其父元素右边线的距离。

// 定位(position)和偏移可以搭配使用,如 top:100px;left:30px;

[ 叠放次序 z-index ]当对多个元素同时设置定位时,定位元素之间就可能会发生层叠。

其用于设置 Z 轴上得排序,默认值为 0 ,但可设置为负值,也就是说其取值可以为:正整数、负整数和0。

(如不做设置,或取值相同,则按照文档流的顺序排列,后面的元素将置于前面的元素之上)

z-index默认属性值为0,取值越大,定位元素在层叠元素中越居上。但z-index栈除外。

[ z-index 栈 ]父类容器的 z-index 优于子类 z-index。


[2] position?↓ :用于定义元素的定位模式(不同的定位的类型)

position : static | relative | absolute | fixed

position:static;       // 自动定位,默认值
positon:relative;      // 在文档流中;参照物为元素本身;使用场景:作为绝对定位元素的参照物;
position:absolute;     // 脱离文档流;默认宽度为内容宽度;参照物为第一个定位元素或根元素;
position:fixed;        // 脱离文档流;默认宽度为内容宽度;参照物为视窗,即整个浏览器窗口;

[ 静态定位 static ] 默认值,可以将元素定位于静态位置,即各元素在HTML文档流中的默认位置(标准流特性)。

在静态定位状态下,无法通过边偏移属性(top、bottom、left、right)来改变元素的位置。

其本身没有什么特别的作用,一般用来清除定位,也就是说不想定位了。

[ 相对定位 relative ] 相对定位是将元素相对于它在标准流中的位置进行定位,不脱离文档流。

对元素设置相对定位后,可以通过边偏移属性改变元素的位置,但是它在文档流中的位置仍然保留。

每次移动的位置,是以自己的左上角为基点进行移动(参照物是自身)。其主要作用是给绝对定位做参照物。

[ 绝对定位 absolute ] 绝对定位可以通过边偏移属性移动位置,但它脱离文档流,默认宽度为内容宽度,不占位置。

需要注意的是:如果文档可滚动,绝对定位元素会随着它滚动,因为元素最终会相对于正常流的一部分定位。

其参照物为第一个定位元素或根元素。也就是说,绝对定位依据已经定位(相对、绝对或固定)的父元素(祖先)进行定位;如果其祖先元素都没有定位,就以浏览器(根元素)为基准进行定位。

[ 固定定位 fixed ] 固定定位是绝对定位的一种特殊形式,类似正方形是一种特殊的矩形。  // IE6等低版本浏览器不支持

当对元素设置固定定位后,它将脱离标准文档流的控制,始终依照浏览器窗口来定义自己的显示位置。不管浏览器窗口的大小如何变化,该元素都会始终显示在浏览器窗口的固定位置。

  • 固定定位的元素与父元素没有任何关系,只和浏览器有关;
  • 固定定位完全脱离文档流,不占有位置,不随滚动条滚动。

// 模式A 轮播头图

HTML    <div class="is">
	    <img src="images/first.jpg">
            <p class="title"><a href="#">第一视角</a></p>
            <div class="controls">
	        <span></span><span></span><span></span><span></span>
            </div>
       </div>
CSS    .is{position:relative;width:900px;}
       .is .title{position:absolute;bottom:0;width:100%;}
       .is .controls{position:absolute;bottom:20px;right:10px;}
       .is .controls span{display:inline-block;width:10px;height:10px;}

// 模式B 三行自适应

HTML    <div class="head">head</div>
        <div class="main">main body</div>
        <div class="foot">foot</div>
CSS     .head{display:absolute;height:100px;top:0;left:0;width:100%;}
	    .main{display:absolute;top:100px;bottom:100px;left:0;right:0;}
	    .foot{ display:absolute;height:100px;bottom:0;left:0;width:100%;}

// 模式C 固定顶栏

HTML  <body>
            <div class="top">top bar</div>
            <div class="main">main content</div>
	  </body>
CSS       body{padding:50px;}
          .top{position:fixed;top:0;width:100%;height:50px;}

// 模式D 遮罩

HTML    <div class="mask"></div>
CSS     .mask{position:fixed;top:0;left:0;z-index:999;width:100%;height:100%;}