第04讲:掌握 CSS 精髓:布局

189 阅读4分钟

本文已参与「新人创作礼」活动.一起开启掘金创作之路。

第04讲:掌握 CSS 精髓:布局

CSS

CSS虽然初衷是用来美化HTML文档的 实际上随着float、position等属性的出现它已经可以起到调整文档渲染结构的作用了 随着弹性盒子以及网格布局的推出,cSS将承担越来越重要的布局功能

HTML 标签决定了页面的逻辑结构 CSS 决定了页面的视觉结构

布局的两个共同的

  • 大多数用于PC端 因为PC端屏幕像素宽度够大,可布局的空间也大
  • 布局是有限空间内的元素排列方式 因为页面设计横向不滚动,纵向无限延伸 所以大多数时候讨论的布局都是对水平方向进行分割

单列布局

单列布局是最常用的一种布局 实现效果就是将一个元素作为布局容器 通常设置一个较小的(最大)宽度来保证不同像素宽度屏幕下显示一致

单列布局往往与其他布局结合使用

  • 优势在于基本上可以适配超过布局容器宽度的各种显示屏幕
  • 缺点也是源于此,过度的冗余设计必然会带来浪费 在上面的例子中,其实我的屏幕宽度可以显示更多的内容但是页面两侧却出现了大量空白区域

2列布局

2列布局的实现效果就是将页面分割成左右宽度不等的两列

  • 宽度较小的列设置为固定宽度,剩余宽度由另一列撑满
  • 宽度较小的列父元素为次要布局容器
  • 宽度较大的列父元素为主要布局容器

3列布局

3列布局按照左中右的顺序进行排列通常中间列最宽,左右两列次之

布局实现

通过归纳法找到这些方式的共同实现步骤

  1. 为了保证主要布局容器优先级,应将主要布局容器写在次要布局容器之前
  2. 将布局容器进行水平排列
  3. 设置宽度,即次要容器宽度固定,主要容器撑满
  4. 消除布局方式的副作用,如浮动造成的高度塌陷
  5. 为了在窄屏下也能正常显示,可以通过媒体查询进行优化

单列布局

单列布局通过布局容器(最大)宽度以及左右边距为auto即可实现

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>单列布局</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      width: 500px;
      margin: auto;
    }

    header,
    section,
    footer {
      margin: 10px auto;
      border: 1px solid black;
    }

    header,
    footer {
      height: 32px;
    }

    header {
      background-color: pink;
    }

    section {
      background-color: skyblue;
    }

    footer {
      background-color: green;
    }
  </style>
</head>

<body>
  <header></header>
  <section>
    <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
  </section>
  <footer></footer>
</body>

</html>

效果图:

image.png

2列布局

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>2列布局</title>
  <!-- 为了方便查看,给布局容器设置了高度和颜色 -->
  <style>
    main,
    aside {
      height: 100px;
    }

    main {
      background-color: pink;
    }

    aside {
      background-color: skyblue;
    }

    .wrap {
      display: flex;
    }

    .main {
      flex: 1
    }

    .aside {
      /* flex: 1; */
      width: 200px;
    }

    @media only screen and (max-width:1000px) {
      .wrap {
        flex-direction: row;
      }

      .main {
        flex: 100%
      }
    }
  </style>
</head>

<body>

</body>
<div class="wrap">
  <main class="main">主要布局容器</main>
  <aside class="aside">次要布局容器</aside>
</div>

</html>

效果图:

image.png

3列布局

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>3列布局</title>
  <style>
    .main,
    .left,
    .right {
      height: 100px;
      float: left;
    }

    .main {
      background-color: red;
      width: 100%;
    }

    .left {
      background-color: green;
      width: 300px;
      position: relative;
      left: -300px;
      margin-left: -100%;
    }

    .right {
      background-color: blue;
      width: 200px;
      position: relative;
      margin-left: -200px;
      right: -200px;
    }

    .wrap {
      padding: 0 200px 0 300px;
    }

    .wrap::after {
      content: '';
      display: block;
      clear: both;
    }

    @media screen and (max-width:1000px) {
      .wrap {
        padding: 0;
      }

      .left {
        left: 0;
        margin-left: 0;
      }

      .right {
        margin-left: 0;
        right: 0;
      }
    }
  </style>
</head>

<body>
  <div class="wrap">
    <main class="main">main</main>
    <aside class="left">left</aside>
    <aside class="right">right</aside>
  </div>
</body>

</html>

效果图: image.png 注意:
如果给left,right直接设置高度的话,布局容器left和right都会换行
所以需要通过设置父元素wrap内边距来压缩主要布局main,给次要布局容器留出空间
同时通过设置次要布局容器边距,以及采用相对定位调整次要布局容器至两侧

延伸1:垂直方向的布局

垂直方向有一种布局虽然使用频率不如水平方向布局高,但在面试中很容易被问到 这种布局将页面分成上、中、下三个部分上、下部分都为固定高度,间部分高度不定

  • 当页面高度小于浏览器高度时,部分应固定在屏幕底部
  • 当页面高度超出浏览器高度时,部分应该随中间部分被撑开,显示在页面最底部
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>垂直方向的布局</title>
  <style>
    .container {
      display: flex;
      height: 100%;
      flex-direction: column;
      box-sizing: border-box;
      min-height: 100vh;
      padding-bottom: 100px;
    }

    header,
    footer {
      min-height: 100px;
      height: 100px;
      background-color: pink;
    }

    main {
      flex: 1;
      background-color: aqua;
    }

    footer {
      margin-top: -100px;
    }
  </style>
</head>

<body>
  <div class="container">
    <header></header>
    <main>
      <div>...</div>
    </main>
    <footer></footer>
  </div>
</body>

</html>

效果图:

image.png

延伸2:框架中栅格布局的列数

Bootstrap提供了12列栅格

从12列说起

  • 12这个数字从数学上来说它具有很多约数1、2、3、4、6、12
  • 也就是说可以轻松实现1等分、2等分、3等分、4等分、6等分、12等分比例方面可以实现1:11、1:5、1:3、1:2、1:1、1:10:1、1:4:1等
  • 如果换成10或8,则可实现的等分比例就会少很多,而更大的16似乎是个不错的选择,但对于常用的3等分就难以实现

elment ui和ant design提供了24列栅格

  • 使用24列不使用12列
  • 可能是考虑宽屏幕(PC端屏幕宽度不断增加)下对12列难以满足等分比例需求
  • 比如8等分
  • 同时又能够保证兼容12列情况下的等分比例(方便项目迁移和替换)