CSS布局方式总结

一、显示(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就是页面上一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然。

圣杯布局和双飞翼布局
事实上,圣杯布局其实和双飞翼布局是一回事。它们实现的都是三栏布局,两边的盒子宽度固定,中间盒子自适应,也就是我们常说的固比固布局。它们实现的效果是一样的,差别在于其实现的思想。
CSS布局方式总结_第1张图片
通过缩放页面就可以发现,随着页面的宽度的变化,这三栏布局是中间盒子优先渲染,两边的盒子框子固定不变,即使页面宽度变小,也不影响我们的浏览。注意:当你缩放页面的时候,宽度不能小于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;}

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

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

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

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

CSS布局方式总结_第4张图片

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

搞定!

圣杯布局table的实现方式


<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 id="left" class="col">#left
<div id="right" class="col">#right
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">我是leftdiv>
        <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>

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

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

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

实现以下效果
CSS布局方式总结_第6张图片

        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>子元素1li>
            <li>子元素2li>
            <li>子元素3li>
            <li>子元素4li>
            <li>子元素5li>
            <li>子元素6li>
            <li>子元素7li>
        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)

你可能感兴趣的:(CSS知识理解)