【CSS全解】CSS布局

151 阅读8分钟

布局概述

  • 把页面分成一块一块,按左中右、上中下等排列。
  • 布局分类
    1. 固定宽度布局:一般宽度为960/1000/1024px,如淘宝。
    2. 不固定宽度布局:依靠文档流的自适应原理来布局,一般在手机上使用。
    3. 响应式布局:一种混合布局,在PC上固定宽度布局,在手机上不固定宽度布局。
  • 布局的两种思路
    • 从大到小:先定下大局,再完善每个部分的小布局。(新人推荐)
    • 从小到大:先完成小布局,再组成成大布局。(老手推荐)
  • div+css布局现在一般使用main、header、footer、nav、aside等代替div来完成布局。
  • 该使用什么布局方式?
    • Pasted image 20220618190519.png

float布局

  • 固定宽度布局。

  • 步骤:

    1. 在子元素上加float和width,也因此子元素不能是inline元素。
    2. 在父元素上加.clearfix
  • .clearfix

    .clearfix::after {
        content: "";
        display: block;
        clear: both;
    }
    
    • 其作用在于让父元素内float: left的子元素不溢出。
    • .clearfix::after中两个:是新语法,IE8以下不支持,可以用.clearfix::after即一个:替代。
  • 出于美观考虑,往往会留一些空间或者最后一个元素不设width,但可以设置一个max-width。

  • 不需要做响应式、不要用float做手机页面,这个布局是专门为IE准备的,而手机上没有IE。

  • 测试边框的border不能直接加到.clearfix中,会出错。

  • IE 6/7 存在双倍margin bug,两种解决办法:

    1. 使用_margin,针对IE 6/7把margin减半,IE 6/7会识别_marginmargin而其他浏览器内核不会。
    2. 为子元素添加一个display: inline-block
  • float布局+header+footer,即可满足几乎所有PC页面需求。

  • 不希望父元素和子元素之间留出空隙?

    • 为父元素添加display: inline-block
  • 如果两个元素高度不固定,怎么才能让两个元素水平方向居中?

    • float布局很难解决,换flex布局。

不同布局

  • 用float做两栏布局:float: left;float: right;.clearfix;
  • 用float做三栏布局:float: left;float: left;float: left;.clearfix;
  • 用float做四栏布局:float: left;float: left;float: left;float: left、.clearfix;
  • 用float做平均布局:为单元格添加一个父级元素x,它的margin为负数,方向为子元素中兄弟元素间隔的margin方向、他的值为子元素中兄弟元素的margin的值。(负margin
    • 负margin只对左右生效,对上下不生效。
    • 使用负margin要注意父元素的border会影响内部剩余空间大小。

flex布局

Pasted image 20220618230945.png

  • flex布局的小游戏
  • flex布局中,永远不要把width和height写死,除非特殊说明。
    • 一般在PC端会写死,在手机端不会写死。
    • 什么叫不写死?不使用px,例如50%、30vw;或者使用min、max前缀。
  • 尽量使用min-width、max-width、min-height、max-height来替代width和height。
  • flex可以基本满足所有需求。
  • flex和margin-xxx: auto配合有意外效果。

container的CSS样式

让一个元素变成flex容器

  • display: flex;推荐。新的flex容器会另起一行(block-flex)。
  • display: inline-flex;:新的flex容器会拼成一行(inline-block-flex)。

改变items流动方向(主轴)

  • flex-direction: row;默认。从左往右排。
  • flex-direction: row-reverse;:从右往左排。
  • flex-direction: column;:从上往下排。
  • flex-direction: column-reverse;:从下往上排。

控制items是否换行

  • flex-wrap: nowrap;默认。不换行,此时items占满一行后,会改变元素宽度,强行挤在一行。
  • flex-wrap: wrap;推荐。换行。
  • flex-wrap: wrap-reverse;:从下往上排列并换行。

主轴对齐方式

  • 主轴方向有空余时,items要如何分布方式。
  • justify-content: flex-start;默认。把多余空间放在最末。
  • justify-content: flex-end;:把多余的空间全部放到最首。
  • justify-content: center;:把多余的空间全部放到两边。
  • justify-content: space-between;:把多余的空间放到中间,头尾item会顶到container。
    • 对于双items,可以在lastChild中加margin-left: auto;,来代替space-between(推荐)。
  • justify-content: space-around;:把多余的空间均分,items不会顶到。

次轴对齐方式

  • align-items: flex-start;默认。从次轴开始位置开始排列。
  • align-items: flex-end;:从次轴结尾位置开始排列。
  • align-items: center;:居中排列。
  • align-items: stretch;:自动拉伸,使items在次轴方向上填满。要求items不能有给定width或height。

多行内容会如何分布

  • 多行情况下,次轴方向有空余时,items要如何分布。
  • align-content: flex-start;:把多余的空间全部放到最末。
  • align-content: flex-end;:把多余的空间全部放到最首。
  • align-content: center;:把多余的空间全部放到两边。
  • align-content: strech;默认。把多余的空间均分,第一个item会顶到。
  • align-content: space-between;:把多余的空间放到中间,头尾item会顶到container。
  • align-content: space-around;:把多余的空间均分,items不会顶到。
  • align-items和align-content的区别,align-content属性几乎不用,可以暂时不用过多纠结。

.item的CSS样式

  • order属性
    • 通过给order赋值,items会按order从小到大排列。
    • 默认order: 0;
    • order值可以是负数。
  • flex-grow属性
    • 决定了在分配container多余空间时,item所占有空间的权重,属性值越大,所占的比例约高。
    • 默认flex-grow:0;
    • 要求item不能给定width值。
    • 不能是负数(没有效果)。
    • 在制作nav时,logo、导航、头像item的flex-grow值一般为0、1、0。
  • flex-shrink属性
    • 决定了在container空间不足时,item缩放多少的权重,属性值越大,缩放的越多。
    • 默认flex-shrink: 1;
    • 要求container样式为flex-wrap: nowrap;,items有原始width并且占满一行。
    • 一般通过flex-shrink: 0;防止缩放。
  • flex-basis
    • 控制基准宽度,和width差不多。
    • 默认flex-basis: auto;
  • flex
    • flex-grow和flex-shrink的复合属性。
    • flex: flex-grow值和flex-shrink值,例:flex: 1;
    • flex: flex-grow和flex-shrink值 width,例:flex: 1 10px;
    • flex: flex-grow值 flex-shrink值 width,例:flex: 1 0 10px;
  • align-self
    • 控制某一个item在次轴方向上的对齐方式。
    • 属性值与align-items相同。

Grid布局

container的CSS样式

让一个元素成为Grid的container

  • display: grid;:类似于flex。
  • display: inline-grid;:类似于inline-flex。

设置container的行和列

  • grid-template-columns: 宽度1 宽度2 宽度3…:分割宽度。
  • grid-template-row: 高度1 高度2 高度3…:分割高度。
  • 注意
    • 默认情况下,一个子元素占一个网格。
    • 宽度和高度可以是px、auto、百分数、fr。
    • fr为单位时,会以“一份”为单位,对行和列进行切割。如1fr 1fr 1fr就是以1:1:1的方式切割三份。而1fr 2fr 1fr就是以1:2:1的方式切割三份。

设置网格之间的空隙

  • grid-gap: 数值:设置所有格子之间的空隙。
  • grid-column-gap: 数值:设置垂直方向的格子之间的空隙。
  • grid-row-gap: 数值:设置水平方向的格子之间的空隙。

grid-template-areas

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        .container {
            /* 一定要设置最小高度 */
            min-height: 100vh; 
            border: 1px red solid;
            display: grid;
            grid-template-areas: 
                /* 这里有用 . 来代表空白区域 */
                "header header ."
                "aside main ad"
                ". footer footer"
            ;
            grid-template-rows: 60px auto 60px;
            grid-template-columns: 100px auto 100px;
        }

        .container > * {
            border: 1px black solid;
        }

        .container > header {
            grid-area: header;
        }

        .container > aside {
            grid-area: aside;
        }

        .container > main {
            grid-area: main;
        }

        .container > .ad {
            grid-area: ad;
        }

        .container > footer {
            grid-area: footer;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>header</header>
        <aside>aside</aside>
        <main>main</main>
        <div class="ad">ad</div>
        <footer>footer</footer>
    </div>
</body>
</html>
  • 用grid-template-areas完成排版步骤
    1. 给container添加grid-template-areas属性,赋予字符串值,分割并命名区域。
    2. 给items添加grid-area属性,赋予对应的区域名字作为值。
  • 注意
    • 一般用.表示空白区域。
    • 多个auto时,一定要设置最小高度。

items的CSS样式

  • 给items设置范围
    • grid-column-start: 线:纵向从第几根线开始。
    • grid-column-end: 线:纵向到第几根线结束。
    • grid-row-start: 线;:横向从第几根先开始。
    • grid-row-end: 线;:横向到第几根线结束。
  • 注意
    • 线从1开始计数,没有第0根线,可以是负数。
    • 有n行(列),就有n+1跟线。
    • 可以给线自定义名字。

拓展

去除图片下方多余的部分

  • 为图片元素添加以下两者其一
    1. vertical-align: top;
    2. vertical-align: middle;

用outline来调试布局

  • 由于box-sizing: border会计算border的宽度,偶尔会干扰布局(尤其是父元素的border)。
  • 可以采用outline来替代border,后者效果几乎与border相同,但不会计算在盒模型的宽度内。

block元素水平居中的方法

  • 如果父元素为固定width,可使用margin: 0 auto;使之水平居中。
  • 只对block元素有用,inline-block元素也不行。
  • margin: 0 auto;更优解
    margin-left: auto;
    margin-right: auto;
    

方方の敦敦教诲

  • 其一:CSS重要原则,不该写的代码不要写。
  • 其二:不要使用任何非约定俗成的英文单词缩写。
  • 其三:CSS最忌讳的就是把width和height写死。
  • 其四:必须先有/完成设计稿,老板肯定、再写代码。
  • 其五:设计师不给设计稿,就不做,设计不属于前端的工作范围。要几套界面,必须要有几套设计稿。(底线