css|关于布局你需要掌握🏆的知识点

528 阅读15分钟

1、布局单位

1、px

布局的默认单位,一般没有特殊需求,就设置单位是px

2、em

相对于父元素的font-size,如果父元素没有设置font-size,相对于浏览器的默认字体尺寸(默认16px)

例子:父元素是20px,子元素是2em,那子元素就是40px

3、rem

相对于根元素的font-size(html元素)

比如:一个元素1100px,html font-size:50px,那元素就是22rem(1100rem / 50 = 22 rem)

4、%

大部分相对于祖先元素,也有相对于自身的情况比如(border-radius、translate等)

5、vm/vh

相对于视窗的尺寸

1vw就是视口的1%,当视口是1200px,1vw = 1200 * 0.01 = 12px ,如果是50vw就是视口的50%,50vw = 1200 乘以 0.5 = 600px

2、两栏布局

两栏布局就是左边固定,右边自适应的布局方式

1、float+calc计算属性

左右都左浮,保证在一行,右侧使用calc计算属性,减去100px

        .left {
            float: left;
        }

        .right {
            float: left;
            width: calc(100% - 100px);
        }

2、 float + margin-left

左侧左浮,宽度设置100px,右侧设置margin-left: 100px;

        .left {
            float: left;
            width: 100px;
        }

        .right {
            margin-left: 100px;
        }

3、float + overflow

左侧左浮,右侧元素设置overflow: hidden; 这样右边就触发了BFC,BFC的区域不会与浮动元素发生重叠,所以两侧就不会发生重叠

        .left {
            float: left;
        }

        .right {
            overflow: hidden;
        }

4、absolute+margin

利用绝对定位,将父级元素设置为相对定位。左边元素设置为absolute定位,并且宽度设置为100px。将右边元素的margin-left的值设置为100px。

        .box {
            position: relative;
        }

        .left {
            position: absolute;
            top:0;
            left: 0;
            width: 100px;
        }

        .right {
            margin-left: 100px;
        }

5、absolute+left

利用绝对定位,将父级元素设置为相对定位。左边元素宽度设置为100px,右边元素设置为绝对定位,left设置为100px,其余方向定位为0。

        .box {
            position: relative;
        }

        .left {
            width: 100px;
        }

        .right {
            position: absolute;
            left: 100px;
            top: 0px;
            right: 0px;
        }

6、flex布局

利用flex布局,将左边元素设置为固定宽度100px,将右边的元素设置为flex:1。

        .box {
            display: flex;
        }

        .left {
            flex: 0 1 100px;
        }

        .right {
            flex: 1;
        }

7、table实现

        .box {
            display: table;
        }

        .left {
            display: table-cell;
            width: 100px;
        }

        .right {
            display: table-cell;
        }

3、三栏布局

1、流体布局

  • 利用浮动,左右两栏设置固定大小,并设置对应方向的浮动。中间一栏设置左右两个方向的margin值,注意这种方式,中间一栏必须放到最后
        .left {
            float: left;
            width: 100px;
        }

        .center {
            margin-left: 100px;
            margin-right: 100px;
        }

        .right {
            float: right;
            width: 100px;
        }

2、圣杯布局

  • 圣杯布局,利用浮动和负边距来实现。父级元素设置左右的 padding,三列均设置向左浮动,中间一列放在最前面,宽度设置为父级元素的宽度,因此后面两列都被挤到了下一行,通过设置 margin 负值将其移动到上一行,再利用相对定位,定位到两边

        .left {
            float: left;
            width: 100px;
            margin-left: -100%;
            position: relative;
            left: -100px; 
            
        }

        .center {
            float: left;
            width: 100%;
        }

        .right {
            float: left;
            width: 100px;
            margin-left: -100px;
            position: relative;
            right: -100px;
        }

        .main {
            padding: 0 100px;
        }

3、双飞翼布局

  • 双飞翼布局,双飞翼布局相对于圣杯布局来说,左右位置的保留是通过中间列的 margin 值来实现的,而不是通过父元素的 padding 来实现的。本质上来说,也是通过浮动和外边距负值来实现的
        .main {
            float: left;
            width: 100%;
        }

        .center {
            margin: 0 100px;
        }

        .left {
            float: left;
            width: 100px;
            margin-left: -100%; 
        }

        .right {
            float: left;
            width: 100px;
            margin-left: -100px;
        }

4、flex

  • 利用flex布局,将左边元素设置为固定宽度100px,将右边的元素设置为flex:1。
        .main {
            display: flex;
        }

        .left {
            width: 100px;
        }

        .center {
            flex: 1;
        }

        .right {
            width: 100px;
        }

4、垂直居中

有宽高的情况

1、transform + absolute

  • 利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过translate来调整元素的中心点到页面的中心。该方法需要考虑浏览器兼容问题。
        .parent {
            position: relative;
        }
        .diva {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }

2、margin +relative

  • 元素使用margin 0 auto,会达到水平居中的效果,然后操作垂直居中,设置position: relative; top: 50%; transform: translateY(-50%);
        .diva {
            /* 水平居中*/
            margin: 0 auto;
            position: relative;
            /* 垂直居中 */
            top: 50%;
            transform: translateY(-50%);
        }

3、flex

  • 容器设置flex,align-items: center;justify-content: center;

        .parent{
            display: flex;
            align-items: center;
            /*垂直居中*/
            justify-content: center;
            /*水平居中*/
        }

4、绝对定位+ margin: auto

  • 利用绝对定位,设置四个方向的值都为0,并将margin设置为auto,由于宽高固定,因此对应方向实现平分,可以实现水平和垂直方向上的居中。
        .parent {
            position: relative;

        }

        .child {
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            margin: auto;
        }

5、相对定位+margin负值

  • 利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过margin负值来调整元素的中心点到页面的中心。
        .parent {
            position: relative;
        }

        .child {
            position: absolute;
            top: 50%;
            left: 50%;
            margin-top: -50px;
            /* 自身 height 的一半 */
            margin-left: -50px;
            /* 自身 width 的一半 */
        }

无宽高的情况

1、相对布局+transform

  • 核心思想(子元素无宽高):父元素 position: relative;设置相对定位,然后top:50%;left:50%;然后利用transform: translate(-50%, -50%);
    .index {
        position: relative;

    }
    .index-dialog{
        position:absolute;
        left: 50%;
        top:50%;
        transform: translate(-50%,-50%);
    }

2、伪元素

    .out_box {
        /*使块元素中的行内块元素水平居中*/
        text-align: center;

    }

    .out_box:after {
        content: "";
        /*使新建的伪元素和子元素保持在一行,且可以设置宽高*/
        display: inline-block;
        /*使伪元素高度等于父元素*/
        height: 100%;
        /*设置基线为中间*/
        vertical-align: middle;
    }

    .in_box {
        width: 100px;
        height: 100px;
        display: inline-block;
        /*使得基线和伪元素基线对齐*/
        /*作用是不换行,且当父元素设置text-align:center时,子元素(行内块)水平对齐*/
        vertical-align: middle;
    }

3、flex

  • 核心思想(子元素无宽高):容器设置flex,align-items: center;justify-content: center;
    .index {
        display: flex;
        align-items: center;
        justify-content: center;

    }

4、table

  • 核心思想(子元素无宽高):父元素设置display:table-cell;text-align: center;vertical-align: middle;子元素设置如果是块元素:display: inline-block;

    .index {
        display: table-cell;
        text-align: center;
        vertical-align: middle;
    }

    .index-dialog {
        display: inline-block;
    }

5、品字布局

image (22).png

浮动实现

我们可以使用定位实现,对于上面的1,使用magin属性让他水平居中;下面的两个使用浮动即可实现,其HTML结构如下:

        div {
            width: 100px;
            height: 100px;
            line-height: 100px;
            text-align: center;

        }

        .div1 {
            margin: 0 auto;
        }

        .div2 {
            float: left;
            margin-left: 50%;
        }

        .div3 {
            float: left;
            margin-left: -200px;
        }

inline-block实现

这里将div设置为了inline-block,实际上和上面的float的作用是一眼的,就是让下面的两个块不换行。使用CSS样式如下

        div {
            width: 100px;
            height: 100px;
            line-height: 100px;
            text-align: center;

        }

        .div1 {
            margin: 0 auto;
        }

        .div2 {
            display: inline-block;
            margin-left: 50%;
        }

        .div3 {
            display: inline-block;
            margin-left: -200px;
        }

思考💡:对margin-left:-200px的理解?

一开始利用margin使得1居中, 接下来就是处理2,3 ,首先要满足2,3在一行,那就是float或者inline-block,完成之后,对2设置 margin-left: 50%;会出现如图所示:

image (23).png

接下来就是对3的处理,先把3展示在页面上,很明显3需要向左移动2个盒子的单位,所以就设置 margin-left: -200px实现。

image (24).png

6、九空格布局

image (25).png

1、flex布局

由于我们给每个元素设置了下边距和右边距,所以最后同一列(3、6、9)的右边距和最后一行(7、8、9)的下边距撑大了ul,所以这里使用类型选择器来消除他们的影响。最终的实现代码如下:

   ul {
            display: flex;
            flex-wrap: wrap;
        }

        li {
            width: 30%;
            height: 30%;
            margin-right: 5%;
            margin-bottom: 5%;
        }

        li:nth-of-type(3n) {
            margin-right: 0;
        }

        li:nth-of-type(n+7) {
            margin-bottom: 0;
        }

2、grid布局

grid布局相对于flex布局来说,实现九宫格就更加容易了,只需要设置几个属性即可:其中grid-template-columns属性用来设置每一行中单个元素的宽度,grid-template-rows属性用来设置每一列中单个元素的高度,grid-gap属性用来设置盒子之间的间距。

        ul {
            display: grid;
            grid-template-columns: 30% 30% 30%;
            grid-template-rows: 30% 30% 30%;
            grid-gap: 5%;
        }

3、float

这里首先需要给父元素的div设置一个宽度,宽度值为:盒子宽 * 3 + 间距 * 2;然后给每个盒子设置固定的宽高,为了让他换行,可以使用float来实现,由于子元素的浮动,形成了BFC,所以父元素ul使用overflow:hidden;来消除浮动带来的影响。最终的实现代码如下


        ul {
            flex-wrap: wrap;
            overflow: hidden;
        }

        li {
            float: left;
            width: 30%;
            height: 30%;
            margin-right: 5%;
            margin-bottom: 5%;
        }

        li:nth-of-type(3n) {
            margin-right: 0;
        }

        li:nth-of-type(n+7) {
            margin-bottom: 0;
        }

4、inline-block

其实inline-block的作用和上面float的作用是一样的,都是用来让元素换行的,实现代码如下:

    ul {
            flex-wrap: wrap;
            letter-spacing: -10px;
        }

        li {
            display: inline-block;
            width: 30%;
            height: 30%;
            margin-right: 5%;
            margin-bottom: 5%;
        }

        li:nth-of-type(3n) {
            margin-right: 0;
        }

        li:nth-of-type(n+7) {
            margin-bottom: 0;
        }

需要注意的是,设置为inline-block的元素之间可能会出现间隙,就可能出现下面这种情况。

image (26).png

这里使用了letter-spacing属性来消除这种影响,该属性可以用来增加或减少字符间的空白(字符间距)。使用之后就正常了,出现了预期的效果。也可以给ul设置font-size: 0;来消除盒子之间的字符间距。

5、table布局

table布局也不算太难,首先给父元素设置为table布局,然后使用border-spacing设置单元格之间的间距,最后将li设置为表格行,将div设置为表格单元格,CSS样式如下:

        .table {
            display: table;
            border-spacing: 10px;
        }

        li {
            display: table-row;
        }

        div {
            width: 30%;
            height: 30%;
            display: table-cell;
        }

思考💡:nth-of-type()和nth-child()的区别?

    <div id="wrap">
        <p>one</p>
        <div>我是div</div>
        <p>two</p>
        <p>three</p>
        <p>four</p>
        <p>five</p>
        <p>six</p>
    </div>
        #wrap p:nth-of-type(3) {
            color: red;
        }

        #wrap p:nth-child(3) {
            color: green;
        }

判断变红和变绿的是哪个?

image (27).png

通过结果可以分析:

p:nth-of-type(3)代表的就是,所有兄弟节点中找标签为p的,然后找到的第三个p标签背景为红色

注意:不要和:nth-child(3)搞混了,上面的背景变绿的是two,因为,该选择器是找父元素的第三个子元素,如果该子元素为p,则其变为绿色,如果,第三个子元素不是p元素,则没有子元素的背景变为绿色

思考💡:nth-of-type(n)中n的含义?

ele:nth-of-type(n)表示选择父元素下的第 nele元素,其中 n 可以是正整数、公式或者关键字。同时,ele 一般是标签选择器。

1、n做为整数

当n做为一个具体的数时,从1开始生效。

  li:nth-of-type(1), li:nth-of-type(4) {
    background-color: #eee;
    color: #1890ff;
  }

2、n做为关键字

even | odd,选择偶数还是奇数。

  li:nth-of-type(even) {
    background-color: #eee;
    color: #1890ff;
  }

3、n做为公式

作为公式时, n 是从 0 开始的。

 li:nth-of-type(n+2) :nth-of-type(-n+4) {
  background-color: #eee;
  color: #1890ff;
}

7、flex布局

flex布局,容器的属性,项目的属性

容器的属性

flex-direction 设置主轴的方向:row水平,column垂直,row-reverse 水平相反,column 垂直相反

justify-content:flex-start 左对齐,flex-end 右对齐,center 中间对齐,space-between 两端对齐,项目之前的间距相等,space-around:每个项目之前的间隔相等,所以项目之间的间距比两端的间隔大

align-items:交叉轴,flex-start 左对齐,flex-end 右对齐,center 中间,stretch 轴线占满整个交叉轴,如果项目没有设置高度,会自动拉伸和容器的高度一致。baseline 项目中的第一行文字的基线对齐

flew-wrap:默认不换行,设置wrap后,可自动换行,wrap-reverse 第一行在下方

flex-flow:是flex-direction,flex-warp的缩写,默认是row nowarp 水平排列 不换行

align-content:当多行设置才会有效 设置值有flex-strart,flex-end,center,space-between,space-around,stretch

项目的属性

order:项目的排序,值越小越在前面

flex-grow:项目的放大比例,默认为0(不放大),如果都是1,就平分,如果是2,占据的空间比其他大一倍

flex-shink:项目的缩小比例,默认是1,空间不够,主动缩小,如果是0,就不缩小

flex-basis:定义项目占主轴的空间,默认是项目自身的大小

flex:是flex-grow、flex-shink、flex-basis的缩写,默认值是0 1 auto

align-self:单个项目有不同的对齐方式,flex-start,flex-end,center,stretch、auto 默认是auto,继承父元素属性,如果父元素没有设置,默认是stretch

思考💡:flex:1 代表的含义?

flex是flex-grow、flex-shink、flex-basis的缩写,默认值是flex:0 1 auto

第一个参数表示: flex-grow 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大;

第二个参数表示: flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小;

第三个参数表示: flex-basis给上面两个属性分配多余空间之前, 计算项目是否有多余空间, 默认值为 auto, 即项目本身的大小。

flex:1 表示flex: 1 1 0%

第一个参数表示: flex-grow 定义项目的放大比例,设置为1,即如果存在剩余空间,该项目将放大;

第二个参数表示: flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小;

第三个参数表示: flex-basis给上面两个属性分配多余空间之前, 计算项目是否有多余空间, 默认值为 0%

特性

任何元素都可以设置弹性布局

设置flex布局以后,子元素的floatclearvertical-align属性都无效

容器的属性

所有子元素自动成为容器的一部分,可以叫做项目,单个项目占据的主轴的空间叫做main-size

image.png

6个基本属性

flex-direction:设置主轴的方向,4个值:row | row-reverse | column | column-reverse

image.png

- `row`(默认值):主轴为水平方向,起点在左端。
- `row-reverse`:主轴为水平方向,起点在右端。
- `column`:主轴为垂直方向,起点在上沿。
- `column-reverse`:主轴为垂直方向,起点在下沿。

flex-wrap:控制项目是否换行,3个值: flex-wrap: nowrap | wrap | wrap-reverse;

nowrap(默认):不换行。
wrap:换行,第一行在上方
wrap-reverse:换行,第一行在下方。

image.png

flex-flow:是flex-direction、flex-warp的缩写,默认值是 row nowrap 水平排列不换行

justify-content:定义项目的对齐方式,5个值:justify-content: flex-start | flex-end | center | space-between | space-around;

image.png

flex-start(默认值):左对齐
flex-end:右对齐
center: 居中
space-between:两端对齐,项目之间的间隔都相等。
space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

align-items :交叉轴(可以理解成一般情况下的垂直轴)5个值:flex-start | flex-end | center | baseline | stretch;

image.png

flex-start:交叉轴的起点对齐。
flex-end:交叉轴的终点对齐。
center:交叉轴的中点对齐。
baseline: 项目的第一行文字的基线对齐。
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

align-content:定义多个维度的对齐方式,如果只有一个轴线,不起作用

image.png

flex-start:与交叉轴的起点对齐。
flex-end:与交叉轴的终点对齐。
center:与交叉轴的中点对齐。
space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
stretch(默认值):轴线占满整个交叉轴。
子元素(项目)属性

order定义项目的排列属性,值越小,越在前面

image.png

flex-gorw:定义项目的放大比例,默认为0,不放大,如果都是1,就平分,如果有一个是2,则占据的空间比其他的大一倍

image.png flex-shink:定义项目的缩小比例,默认是1,如果空间不够,就被挤小,如果值是0,则不会被挤小

image.png

flex-basis:定义项目占据的主轴空间,默认是auto,就是项目本来的大小

flex :是flex-grow、flex-shink、flex-basis的缩写,默认值是 0 1 auto

align-self:允许单个项目有不同的对齐方式 6个值:auto | flex-start | flex-end | center | baseline | stretch;默认值是auto,继承父元素的属性,如果没有父元素,等同于stretch

总结

容器的属性:flex-direction、flex-wrap、flex-flow(flex-direction+flex-wrap)、justify-content、align-items、align-content

项目的属性:order、flex-grow、flex-shink、flex-basis、flex(flex-grow+flex-shink+flex-basis)、align-self

参考👀

flex:1及flex取值的理解