CSS布局方式总结

来源:互联网 发布:汉族智商 知乎 编辑:程序博客网 时间:2024/05/22 03:42

一、显示(display)
1.1 盒模型(box-model)
1.2 行内元素(inline)+块元素(block)
1.3 行内块元素(inline-block)
1.4 flex
1.5 none
二、位置(position)
三、补充
3.1 浮动(float)
3.2 层叠(z-index)
3.3 溢出(overflow)
3.4 resize
3.5 分栏(column)

行内元素和块元素
块元素可以设置宽高、默认占据一行,行内元素不能设置宽高、宽度由其内容决定。块元素默认没有高度,有内容才会有高度。行内元素默认没高度和宽度,有内容才会有。行内元素虽然不能设置宽高,但是设置成绝对定位后,可以设置宽高。
可以将块级元素变成行内元素display:inline;
一行只有一个块元素,但是行内元素可以有多个。
空的块元素将在布局中消失。

位置定位
固定定位fixed不会随着鼠标的滚动而改变位置,固定在屏幕的某一个位置。
绝对定位absolute定位原点是非默认定位(static)的父节点,如果父节点没有这些,那定位原点就是body了,使用了这两种定位中的一种,元素原本占用的布局空间将会消失(脱离文档流)。
相对定位(relative)元素原本占有的布局空间依旧保留在文档流中。相对定位相对原有位置定位。
relative+absolute,父级采用relative,子代采用absolute,子代的定位原点是父级元素的左上角。

FC:Formatting Context,格式化上下文,指页面中一个渲染区域,拥有一套渲染规则,它决定了其子元素如何定位,以及与其他元素的相互关系和作用。
BFC:Block Formatting Context,块级格式化上下文,一个独立的块级渲染区域,该区域拥有一套渲染规则来约束块级盒子的布局,且与区域外部无关。

BFC产生的条件
1. html根元素
2. float的值不为none
3. display的值为inline-block、table-cell、table-caption
4. position的值为absolute或fix

BFC约束规则
1. 生成BFC元素的子元素会一个接着一个防止。垂直方向上他们的起点事一个包含块的顶部,两个相邻子元素之间的垂直距离取决于元素的margin特性。在BFC中相邻的块级元素外边距会折叠,同属一个BFC的两个相邻Box的margin会发生重叠。
2. 生成BFC元素的子元素中,每一个子元素左外边距与包含块的左边界接触,即使浮动元素也是如此(除非这个子元素自身也是一个浮动元素)。
3. BFC的区域不会与float的元素区域重叠。
4. 计算BFC高度时,浮动元素也参与计算。
5. BFC就是页面上一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然。

圣杯布局和双飞翼布局
事实上,圣杯布局其实和双飞翼布局是一回事。它们实现的都是三栏布局,两边的盒子宽度固定,中间盒子自适应,也就是我们常说的固比固布局。它们实现的效果是一样的,差别在于其实现的思想。
双飞翼布局
通过缩放页面就可以发现,随着页面的宽度的变化,这三栏布局是中间盒子优先渲染,两边的盒子框子固定不变,即使页面宽度变小,也不影响我们的浏览。注意:当你缩放页面的时候,宽度不能小于700px,为了安全起见,最好还是给body加一个最小宽度!

我们来看看圣杯布局的实现

第一步:给出HTML结构

    <header><h4>Header内容区</h4></header>    <div class="container">        <div class="middle"><h4>中间弹性区</h4></div>        <div class="left"><h4>左边栏</h4></div>        <div class="right"><h4>右边栏</h4></div>    </div>    <footer><h4>Footer内容区</h4></footer>

写结构的时候要注意,父元素的的三栏务必先写中间盒子。因为中间盒子是要被优先渲染嘛~并且设置其自适应,也就是width:100%。

第二步:给出每个盒子的样式

header{width: 100%;height: 40px;background-color: darkseagreen;}        .container{height:200px;overflow:hidden;}        .middle{width: 100%;height: 200px; background-color: deeppink;float:left;}        .left{ width: 200px;height: 200px;background-color: blue;float:left;}        .right{width: 200px;height: 200px;background-color: darkorchid;float:left;}        footer{width: 100%; height: 30px;background-color: darkslategray;}

中间的三行并没有在一行内显示
大家可以看到,三栏并没有在父元素的一行显示,就是因为中间盒子我们给了百分之百的宽度。所有左右两个盒子才会被挤下来。
那么如何让它们呈现出一行三列的效果呢?那就要让左边的盒子要到中间盒子的最左边,右边的盒子到中间盒子的最右边。换个想法,如果中间盒子不是100%的宽度,那么按照文档流,左边的盒子一定会在中间盒子的后面显示,接着显示右边的盒子。但是现在中间盒子是满屏了的,所以左右两个盒子被挤到下一行显示。我们要做到的是让左右两个盒子都上去。此时,CSS的负边距(negative margin)该上阵了。

第四步:利用负边距布局
1. 让左边的盒子上去
需要设置其左边距为负的中间盒子的宽度,也就是.left {margin-left:-100%;}。这样左盒子才可以往最左边移动。
2. 让右边的盒子上去
需要设置其左边距为负的自己的宽度,也就是.right {margin-left:-200px;}。这样右盒子才可以在一行的最右边显示出自己。
第五步:看此时的效果图
实现固比固布局
我们现在的确是硬性的实现了固比固布局。但是要记住,中间盒子是自适应的宽度,所以中间盒子里的内容会被左右盒子给压住一部分。
第六步:让中间自适应的盒子安全显示

首先:利用父级元素设置左右内边距的值,把父级的三个子盒子往中间挤。

.container{ padding: 0 200px;} 这里的200px是左右盒子的宽度。

利用父级的内边距将盒子往中间挤

其次:给左右两个盒子加一个定位,加了定位之后左右两个盒子就可以设置left和right值。
.left{ position: relative; left: -200px;}.right{position: relative;right: -210px;}

搞定!

圣杯布局table的实现方式

<!DOCTYPE html><html lang="en">    <head>        <meta charset="utf-8">        <style type="text/css">            .wrapper {              height: 100%;              display: table;              width: 100%;              text-align: center;            }            .header {              display: table-row;              height: 1px;              background: #FFD34E;            }            .main {              height: 100%;              display: table;              width: 100%;            }            .box {              display: table-cell;            }            .sidebar {              width: 100px;              background: #BD4932;            }            html, body { height: 100%; }        </style>    </head>    <body>        <div class="wrapper">          <div class="header">头部</div>          <div class="main">            <div class="box sidebar">左侧栏</div>            <div class="box content">主体内容</div>            <div class="box sidebar">有侧栏</div>          </div>          <div class="footer">页脚底部</div>        </div>    </body></html>

双飞翼布局的实现

<div id="container">    <div id="main" class="col">        <div id="main-wrap">#main</div>    </div>    <div id="left" class="col">#left</div>    <div id="right" class="col">#right</div></div>
        body {min-width: 550px;}        #main {width: 100%;height: 400px;background-color: #ccc;float: left;}        #main-wrap {margin: 0 190px 0 190px;}        #left {width: 190px;height: 400px;margin-left: -100%;background-color: #0000FF;float:left;}        #right {width: 190px;height: 400px;margin-left: -190px;background-color: #FF0000;float:left;}

与圣杯布局一样,一开始三个col都设置float: left,为了把left和right定位到左右部分,采用负边距,left部分margin-left: -100%,right部分margin-right: -190px。
之后就是处理main中内容的遮盖问题,只需设置main-wrap的左右外边距即可解决。
相比圣杯布局,双飞翼不必设置左右栏的position: relative,也不必设置左右left、right值,只需多添加一个子元素包含,相应的padding换成margin。总的说来简单不少。

双飞翼布局的好处
主要的内容先加载的优化;
兼容目前所有的主流浏览器,包括IE6在内;
实现不同的布局方式,可以通过调整相关CSS属性即可实现。

其他三列布局的实现方式
三个列固定, 不根据页面变化自适应

<style type="text/css">        .box{            display: -webkit-box;            height: 500px;            width: 1600px;        }        .left{            width: 200px;            background-color: red;        }        .center{            -webkit-box-flex:1;            background: yellow;        }        .right{            width: 300px;            background: blue;        }    </style>    <div class="box">        <div class="left"></div>        <div class="center"></div>        <div class="right"></div>    </div>

center中间宽度固定, left和right自适应

    <style type="text/css">        .box{            display: -webkit-box;            height: 500px;            width: 900px;        }        .left{            -webkit-box-flex:1;            background-color: red;        }        .center{            width: 500px;            background: yellow;        }        .right{            -webkit-box-flex:2;            background: blue;        }    </style>    <div class="box">        <div class="left"></div>        <div class="center"></div>        <div class="right"></div>    </div>

等高布局

    <div class="container">        <div class="left">我是left</div>        <div class="right">我是right<br><br><br>现在我的高度比left高,但left用它的padding-bottom补偿了这部分高度</div>    </div>    <style type="text/css">        *{padding:0; margin:0;}        .container{ width:500px; border:5px solid pink; overflow: hidden;}        .left{ width:200px; background:red; padding-bottom: 2000px; margin-bottom:-2000px; float:left;}        .right{ width:300px; background:yellow; padding-bottom: 2000px; margin-bottom:-2000px; float:left;}    </style>

等高布局
利用CSS3中的display:box,给父元素加display:box;
margin负值对普通文档流的作用如下:
当一个static元素在top/left使用负边距时,它把元素向这个特定的方向拉,但是当你将负边距设置为bottom/right时,它会把它后面的元素往里面拉,从而覆盖自己。

流动方向始终是向上、向左!

左右margin负值对元素宽度的影响:
如果元素没有设置width,左右负边距会把元素向两个方向拉以增加宽度。
实现的前提是:该元素没有设定width属性(当然width:auto是可以的)。

实现以下效果
这里写图片描述

        body,ul,li{padding :0; margin:0;}        ul,li{list-style: none;}        .container{            height: 210px;            width: 460px;            border: 5px solid #000;        }        ul{            height: 210px;            overflow: hidden;            margin-right: -20px;        }        li{            height: 100px;            width: 100px;            background: #09f;            float: left;            margin-right: 20px;            margin-bottom: 10px;        } <body>    <div class="container">        <ul>            <li>子元素1</li>            <li>子元素2</li>            <li>子元素3</li>            <li>子元素4</li>            <li>子元素5</li>            <li>子元素6</li>            <li>子元素7</li>        </ul>    </div></body>

margin负值对绝对定位元素的影响:
绝对定位的元素定义的top、right、bottom、left等值是元素自身的边界到最近的已定位的祖先元素的距离,这个元素自身的边界指的就是margin定义的边界。
如果margin为正的时候,那它的边界是向里收的,如果margin为负的时候,则它的边界是向外扩的。利用这点,就有了经典的利用绝对定位来居中的方法。

    <style type="text/css">        body{padding: 0;margin: 0}        div{            width: 100px;            height: 100px;            background: #f00;            position: absolute;            left: 50%;            top: 50%;            margin-left: -50px;            margin-top: -50px;        }    </style>    <body>        <div></div>    </body>

上下margin重叠传递问题
1、两个普通元素上下的margin会合并为一个margin,哪个大选哪个!

两个浮动元素不会出现margin传递的问题,依然是上面元素的margin-bottom和下面元素的margin-top相加作为两者之间的margin值。

2、两个元素如果是包含关系,父元素和子元素上下margin值也会合并。
对于标准浏览器:
  只有加边框才能避免margin传递!!!
  给父元素添加边框,则子元素和父元素之间的margin就有分割线了,此时将不会发生合并现象了!如果给子元素添加边框两者的margin值还是没有被分开,所以依然还会发生重叠现象!
  


相对定位和绝对定位
相对定位
  内联元素加相对定位也不支持宽高!!relative并不会使元素脱离正常文档流!
以上两点说明加上相对定位不影响元素本身的特性,内联元素和块元素依旧保持原来本身的特性!就是说原来是内联加上relative以后还是内联啦!如果不设置偏移量,相对定位本身并没有什么卵用~

   所以,相对定位要加偏移量,left/top/bottom/right是相对于该元素原来的位置设置偏移量的哦哦哦~

绝对定位
    内联元素变得支持宽高啦~如果没有设置宽度,则内容撑开宽度!!(类似于float,内联元素加上float以后也支持宽高滴!!),会使该元素完全脱离文档流,如果有父级定位则是相对于父级发生偏移,没有定位父级则是相对于body发生偏移!是要搭配偏移量使用啦~

如果直接在body里添加文字和一个<\div>标签
  1. 给<\div>设置absolute定位,不设置偏移量,则<\div>定位在紧接着文字的下面
  2. 给<\div>设置absolute,并且设置偏移量,则

是按偏移量相对于body定位
  3. 给<\div>设置relative,不论是否设置偏移量,都是相对于自己的原来的位置定位。

遮罩实现

    <body>        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        contentcontentcontentcontentcontentcontentcontentcontentcontentcontent<br />        <div class="shadow"></div>        <div class="filter"></div>    </body>        body{padding: 0;margin: 0}        .shadow{            position: absolute;            top: 0;            left: 0;            width: 100%;            height: 100%;            background: #000;            opacity: 0.5;        }        .filter{            width: 300px;            height: 200px;            border: 2px solid #000;            background: yellow;            position: absolute;            top: 50%;            left: 50%;            margin-left: -152px;            margin-top: -102px;        }

浮动总结
块的特征
1. 默认独占一行
2. 没有宽度时,默认撑满一排(即父元素有多宽它就是多宽)
3. 支持所有css命令

行内元素的特征
1. 同排可以继续跟同类的标签
2. 内容撑开宽度
3. 不支持宽高(就是写上宽高值也并没有什么卵用~)
4. 上下的margin和padding有问题(不支持上下的margin,对padding的上下设置并没有起到实际的作用。不会挤开上下的元素)
5. 代码换行被解析为一个空格

inline-block的特点和问题
1、在一行显示
2、内联元素支持宽高
3、没有宽度时默认内容撑开宽度
4、标签之间的换行间隙被解析为空格(无论是块元素还是内联元素都会被解析)
5、IE6/7不支持块属性标签的inline-block

浮动的意思就是使元素脱离文档流,按照指定方向发生移动,遇到父级边界或者相邻的浮动元素停了下来。
1. 块在一排显示;
2. 内联元素支持宽高;
3. 无论是块元素还是内联元素没有宽度时默认内容撑开宽度;
4. 脱离文档流;(所以要想法设法清浮动呀~~)
5. 提升层级半层。

如何清浮动呢?
1.父级加height。但是一般网页height值是依据子元素的height和得来的,所以扩展性不好,一般不采用。
2.给所有的父级都添加浮动。但会导致margin左右自动失效
3.给父级加display:inline-block。问题:margin左右auto失效
4.添加<\div class=”clear”><\div>空标签
问题:IE6 最小高度 19px;(解决后IE6下还有2px偏差)在IE6下,高度小于19px的元素高度会被当作19px来处理~
5.添加
清浮动。但这个方法不符合结构、样式、行为三者分离的要求
6.after伪类 清浮动方法(现在主流方法)
.clear:after{content:‘’;display:block;clear:both;} 必须是block才行
.clear{zoom:1;}
其中:
after伪类: 是在元素内部末尾添加容;:after{content”添加的内容”;} IE6,7下不兼容,但是在IE6、7下,浮动元素父级有宽度就不用清浮动!
zoom:1;是为了触发 IE下 haslayout,使元素根据自身内容计算宽高。但是FF 不支持
7.overflow:hidden 清浮动方法;
overflow有包着浮动元素的特点!但在IE6下不兼容,在IE6下包不住浮动元素,即在IE6下没有包元素的特点
问题:需要配合 宽度 或者 zoom:1 来兼容IE6;(如果该父元素有边框,这里写宽度就会给该父级设置相应的宽度,写zoom:1仅仅达到实现轻浮动的目的,边框会包住整个页面的width)

原创粉丝点击