目录
  1. 1. 圣杯布局
  2. 2. 双飞燕布局
  3. 3. flex布局
  4. 4. 绝对定位布局
css几种经典布局的实现方法

题目要求:针对如下DOM结构,编写CSS,实现三栏水平布局,其中left、right分别位于左右两侧,left宽度为200px,right宽度为300px,main处在中间,宽度自适应。

要求:允许增加额外的DOM节点,但不能修改现有节点顺序。

html
1
<div class="container"> 
2
  <div class="main">main</div> 
3
  <div class="left">left</div> 
4
  <div class="right">right</div> 
5
</div>

圣杯布局

  1. 设置基本样式

    css
    1
    .left {
    2
        background: green;
    3
        width: 200px;
    4
    }
    5
    .main {
    6
        background: blue;
    7
    }
    8
    .right {
    9
        background: red;
    10
        width: 300px;
    11
    }
  2. 圣杯布局是一种相对布局,首先设置父元素container的位置:

    css
    1
    .container {
    2
        padding: 0 300px 0 200px;
    3
    }

    实现效果是左右分别空出200px和300px区域

  3. 将主体部分的三个子元素都设置左浮动

    css
    1
    .left,.main,.right {
    2
        float: left;
    3
    }
  4. 设置main宽度为width:100%,让其单独占满一行

    css
    1
    .main {
    2
        background: blue;
    3
        width: 100%;
    4
    }
  5. 设置left和right 负的外边距

    我们的目标是让left、main、right依次并排,但是上图中left和right都是位于下一行,这里的技巧就是使用负的margin-left:

    css
    1
    .left {
    2
        margin-left: -100%;
    3
        background: green;
    4
        width: 200px;
    5
    }
    6
    7
    .right {
    8
        margin-right: -300px;
    9
        background: red;
    10
        width: 300px;
    11
    }

    负的margin-left会让元素沿文档流向左移动,如果负的数值比较大就会一直移动到上一行。关于负的margin的应用也是博大精深,这里肯定是不能详细介绍了。   

    设置left部分的margin-left为-100%,就会使left向左移动一整个行的宽度,由于left左边是父元素的边框,所以left继续跳到上一行左移,一直移动到上一行的开头,并覆盖了main部分(仔细观察,你会发现main里面的字“main”不见了,因为被left遮住了),left上移过后,right就会处于上一行的开头位置,这时再设置right部分margin-left为负的宽度,right就会左移到上一行的末尾。

  6. 接下来只要把left和right分别移动到这两个留白就可以了。可以使用相对定位移动 left和right部分。

    css
    1
    .left,.main,.right {
    2
        postion: relative;
    3
        float: left;
    4
    }
    5
    .left {
    6
        left: -200px;
    7
        margin-left: -100%;
    8
        background: green;
    9
        width: 200px;
    10
    }
    11
    12
    .right {
    13
        right: -300px;
    14
        margin-right: -300px;
    15
        background: red;
    16
        width: 300px;
    17
    }

至此,我们完成了三列中间自适应的布局,也就是传说中的圣杯布局。完整的代码如下:

html
1
<!DOCTYPE html>
2
<html lang="en">
3
<head>
4
    <meta charset="UTF-8">
5
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
    <title>Document</title>
8
    <style>
9
        .container {
10
            padding: 0 300px 0 200px;
11
        }
12
        .left,.main,.right {
13
            postion: relative;
14
            float: left;
15
        }
16
        .left {
17
            left: -200px;
18
            margin-left: -100%;
19
            background: green;
20
            width: 200px;
21
        }
22
        .main {
23
            background: blue;
24
            width: 100%;
25
        }
26
        .right {
27
            right: -300px;
28
            margin-right: -300px;
29
            background: red;
30
            width: 300px;
31
        }
32
    </style>
33
</head>
34
<body>
35
    <div class="container">
36
        <div class="main">main</div>
37
        <div class="left">left</div>
38
        <div class="right">right</div>
39
    </div>
40
</body>
41
</html>

双飞燕布局

圣杯布局和双飞翼布局解决问题的方案在前一半是相同的,也就是三栏全部float浮动,但左右两栏加上负margin让其跟中间栏div并排,以形成三栏布局。不同在于解决 “中间栏div内容不被遮挡”问题的思路不一样。   

他的HTML结构发生了变化:

html
1
<div class="container"> 
2
  <div class="main">
3
      <div class="content">
4
         main 
5
      </div>
6
    </div> 
7
  <div class="left">left</div> 
8
  <div class="right">right</div> 
9
</div>

完整代码如下:

html
1
<!DOCTYPE html>
2
<html lang="en">
3
4
<head>
5
    <meta charset="UTF-8">
6
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
8
    <title>Document</title>
9
    <style>
10
        .left,.main,.right {
11
            float: left;
12
            text-align: center;
13
        }
14
        .left {
15
            margin-left: -100%;
16
            background: green;
17
            width: 200px;
18
        }
19
        .main {
20
            background: blue;
21
            width: 100%;
22
        }
23
        .right {
24
            margin-left: -300px;
25
            background: red;
26
            width: 300px;
27
        }
28
        .content {
29
            margin: 0 300px 0 200px;
30
        }
31
    </style>
32
</head>
33
<body>
34
    <div class="container">
35
        <div class="main">
36
            <div class="content">
37
                main
38
            </div>
39
        </div>
40
        <div class="left">left</div>
41
        <div class="right">right</div>
42
    </div>
43
</body>
44
</html>

双飞翼布局比圣杯布局多使用了1个div,少用大致4个css属性(圣杯布局container的 padding-left和padding-right这2个属性,加上左右两个div用相对布局position: relative及对应的right和left共4个属性,;而双飞翼布局子div里用margin-left和margin-right共2个属性,比圣杯布局思路更直接和简洁一点。简单说起来就是:双飞翼布局比圣杯布局多创建了一个div,但不用相对布局了

flex布局

  1. 首先将container块设置为一个Flex容器

    css
    1
    .container {
    2
        display:flex;
    3
    }

    那么container下属的main、left和right这三个子元素自动成为容器成员,称为 Flex 项目(flex item),简称”项目”。

  2. 对这三个项目做初始设置

    css
    1
    .left {
    2
        background: green;
    3
    }
    4
    .main {
    5
        background: blue;
    6
    }
    7
    .right {
    8
        background: red;
    9
    }
  3. 通过order属性设置排列顺序

    可以看出三个项目的排序方式不一样了,main排在了第一个,要让main在中间,left在左边,可以通过Flex容器下的项目的属性“order”属性来设置:

    css
    1
    .left {
    2
        order: -1;
    3
        background: green;
    4
    }

    对于order属性:定义项目的排列顺序,越小越靠前,默认为0

  4. 通过项目属性flex-grow设置main的放大比例,将空余的空间用main来填充,使三个项目不满一整行;默认为0,也就是对剩余空间不做处理。

    css
    1
    .main {
    2
        flex-grow: 1;
    3
        background: blue;
    4
    }
  5. 通过项目属性flex-basis 设置left和right的固定宽度

    css
    1
    .left {
    2
        order: -1;
    3
        flex-basis: 200px;
    4
        background: green;
    5
    }
    6
    .right {
    7
        flex-basis: 300px;
    8
        background: red;
    9
    }

完整的代码如下:

html
1
<!DOCTYPE html>
2
<html lang="en">
3
<head>
4
    <meta charset="UTF-8">
5
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
    <title>Document</title>
8
    <style>
9
.container {
10
    display:flex;
11
}
12
.main {
13
    flex-grow: 1;
14
    background: blue;
15
}
16
.left {
17
    order: -1;
18
    flex-basis: 200px;
19
    background: green;
20
}
21
.right {
22
    flex-basis: 300px;
23
    background: red;
24
}
25
    </style>
26
</head>
27
<body>
28
    <div class="container">
29
        <div class="main">main</div>
30
        <div class="left">left</div>
31
        <div class="right">right</div>
32
    </div>
33
</body>
34
</html>

绝对定位布局

绝对定位使元素的位置与文档流无关,因此不占据空间。这一点与相对定位不同,相对定位实际上被看作普通流定位模型的一部分,因为元素的位置相对于它在普通流中的位置。

提示:因为绝对定位的框与文档流无关,所以它们可以覆盖页面上的其它元素。可以通过设置 z-index 属性来控制这些框的堆放次序。

言归正传:

绝对定位,就相当于万金油一样的存在,不论什么样的布局,使用绝对定位都能实现,所以对于具体的实现过程就不赘述

引用:https://blog.csdn.net/wangchengiii/article/details/77926868

文章作者: Izzio
文章链接: https://izzio.netlify.com/blog/web/css/64833.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Seventy
ENG