css布局

学习css的主要目的是为了记住各种属性么?NO,最重要的是理解css的定位机制与盒子模型。

接下来,从布局的角度来学习css的定位机制和盒子模型,学习之前还是先来提几个问题

  1. 进行css布局前为什么要学习定位机制和盒子模型?
  2. 在实际的工作中到会用到哪些css布局?

1.css基础

1.1盒子模型
css是用来为页面元素添加样式的,在最开始的时候,开发网页是先将各个尺寸定下来,然后使用最传统的position/float把元素挪到对应的位置,页面上的元素就好像一个个盒子一样,很明显能够得出一个结论:盒子模型是布局的基础,所以在学习css布局前要先来学习盒子模型,盒子模型包括content,padding,border,margin四大部分,如下图:

盒子模型一般分为标准盒子模型和IE盒子模型,前者由w3c规定,后者由微软规定,这两种盒子模型可以通过box-sizing来进行切换,它们最大的区别就是width属性作用的范围,标准盒子的width=content,IE盒子的width=content + padding + border,看下图:

除了标准盒子和IE盒子这种分类方法,一般还将盒子模型分成块级盒子模型和行内盒子模型,这个是根据不同的display属性值划分的,下面是display的可能取值:

块级盒子模型的图在上面已经贴出了,下面是行内盒子模型的图:

1.1.1 盒子模型的margin负值

前面说了盒子模型包括什么内容,对于任意的盒子模型来说,它的四部分内容可以给它们设值也可以不设值,这四个值中margin部分有很多可以探讨的内容,比如它可以设置负值,这一部分之所以复杂,是因为它与display的不同值混合时会有很多不同的情况,比如margin设负值后可能会带来重叠,那具体重叠的情况是怎样的?说不同的重叠情况前,先来理解一下,margin负值是什么意思?margin的值其实是相对于基线来进行移动,对于top,left方向,它们是以其他元素的边框为基线,对于right,bottom方向它们是以自身border为基线,具体看下图:

接下来看看不同的display会对margin重叠造成什么影响

1.表现

1.1 block元素可以使用四个方向的margin值
1.2 inline元素使用上下方向的margin值无效

1.3 inline-block使用上下方向的margin负值看上去无效

2.重叠

2.1 两个block元素重叠时,后面元素可以覆盖前面元素的背景,但无法覆盖其内容

2.2 当两个inline元素,或两个line-block元素,或inline与inline-block元素重叠时,后面元素可以覆盖前面元素的背景和内容

2.3 当inline元素(或inline-block元素)与block元素重叠时,inline元素(或inline-block元素)覆盖block元素的背景,而内容的话, 后面的元素覆盖前面的元素

3.浮动

3.1 block元素与浮动元素重叠时,其边框和背景在该浮动元素之下显示,而内容在浮动元素之上显示

3.2 inline或inline-block元素与浮动元素重叠时,其边框、背景和内容都在该浮动元素之上显示

4.定位

4.1 定位元素(position不为static)覆盖其他元素的背景和内容

4.2 将relative属性值应用于inline元素,由于无法改变其行内元素的本质,所以其上下margin依然存在问题

1.1.2 盒子模型的边距合并

margin合并(collapse)是指块级元素的上外边距与下外边距有时会合并为单个外边距,这种现象只发生在和当前文档流方向的相垂直的方向上,它分为同级元素和父子元素两种,首先是同级元素,具体代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo</title>
<style>
.center{
width: 500px;
background: pink;
margin: 80px auto;
padding: 10px;
}
</style>
</head>
<body>
<div class="center">讨论margin折叠</div>
<div class="center">讨论margin折叠</div>
</body>
</html>

大家可以看下图,虽然有两个80px,但合并成一个80px

接着是父子元素,具体代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo</title>
    <style>
        .center{
            width: 500px;
            background: pink;
            margin: 80px auto;
        }
        .inCenter{
            background: blue;
            margin: 40px 0;
            padding: 10px;
        }
    </style>
</head>
<body>
    <div class="center">
        <div class="inCenter">你好</div>
    </div>
    
</body>
</html>

1.1.3 盒子模型的margin居中

最后这个比较简单,是在布局中常用的一种水平居中的方法,当页面元素的宽度是确定的值的时候,设置margin:0 auto;元素会进行居中,这是因为auto代表左右自适应。

1.1.4 BFC

1.2 定位机制

上面说了盒子模型,知道了css操纵的内容具体是什么样的,接下来就需要把这些盒子放在页面上,在css的定位机制中,position:absolute、relative、static、fixed有这几个取值,先来看看这些取值的不同
position:absolute是将元素以浏览器视口为原点或者以最近的定位元素为原点来进行定位,具体看下面的代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo</title>
    <style>
        .wrapper{
            width:500px;
            height:500px;
            background: pink;
            margin:200px 500px;
        }
        .absolute{
            width: 100px;
            height:100px;
            position:absolute;
            top:50px;
            left:50px;
            background: green;
        }
    </style>
</head>
<body>
  <div class="wrapper">
        <div class="absolute">absolute</div>
  </div>
</body>
</html>


接着是position:relative,他是相对于自身的位置进行偏移,具体看下面的代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo</title>
    <style>
        .wrapper{
            width:500px;
            height:500px;
            background: pink;
            margin:200px 500px;
        }
        .relative{
            width: 100px;
            height:100px;
            position:relative;
            top:50px;
            left:50px;
            background: green;
        }
    </style>
</head>
<body>
  <div class="wrapper">
        <div class="relative">relative</div>
  </div>
</body>
</html>

1.2.2 float定位
上面的是position定位流,除了position定位流,css还有float定位流,原本css发明这个属性并不是用来定位的,但是它确实在定位时很方便,css的float定位会发生高度坍塌,也就是当设置了float时,会使得原本的元素脱离原来的div,使用上面说的BFC就可以解决这个问题,设置clear也可以解决,具体看下面的代码:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>demo</title>
    <style>
        .wrapper{
            background: pink;
            margin:200px 500px;
            border:1px solid #000;
            /*overflow:hidden;*/
        }
        .clear{
            clear:both;
        }
        .float{
            width: 100px;
            height:100px;
            float:left;
            background: green;
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <div class="float">relative</div>
        //<div class="clear"></div>
    </div>
</body>
</html>