css弹性布局-基础知识篇

    更新时间: 2022-03-31 23:51:04
    点击量: 593

    简介:在块级元素 + float + position 的情况下,再加上一calc的css计算函数 基本也能解决所有布局问题了, 弹性布局是目前的主流方案

    文章均为个人原创, 搬运请附上原文地址感谢, 原文来自MasterYi博客

    • 本篇讲述弹性布局 flex, 尤其是目前IE占比大幅下降后, 前端的主流布局方式 (尤其是移动端, 目前移动web基本都是弹性布局)
    • 本篇将会比较长, 建议学习的过程中自行编写例子巩固
    • 在块级元素 + float + position 的情况下,再加上一calc的css计算函数 基本也能解决所有布局问题了, 弹性布局是目前的主流方案
    • 在学习弹性布局前, 建议先熟悉 块级元素知识盒子模型
    • 设为Flex布局以后, 子元素的浮动特性会失效, 相当于子元素的float、clear和vertical-align属性将失效

    兼容度

    • 兼容目前使用的所有浏览器, 谷歌目前都 99+ 了, 兼容度应该就不用过多描述了

    xx

    认识弹性布局

    • 任何技术的出现都是为了解决难题, 首先让我们分析一下弹性布局解决了什么难题
    • 首先第一点弹性布局简便、如其名弹性、响应式
    • 一些特殊布局, 垂直居中布局问题无需通过js计算, 几行代码便能轻易解决
    • 接下来我们设定一下我们的演员 接下来我们请出老演员 A - E 加他们的老大哥 box, 方便讲解
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>弹性布局</title>
    </head>
    <style>
        .box{
            width: 350px;
            margin: 10px;
            height: 300px;
            border: 2px solid;
            padding: 10px;
            display: flex;
            flex-direction: row;
        }
        .box div{
            height: 100px;
            width: 100px;
            border: 1px solid #ccc;
            border-radius: 5px;
            text-align: center;
            font-size: 24px;
            line-height: 100px;
        }
    </style>
    <body>
    <div class="box">
        <div class="A">A</div>
        <div class="B">B</div>
        <div class="C">C</div>
        <div class="D">D</div>
        <div class="E">E</div>
    </div>
    </body>
    </html>
    • 首先弹性布局主要两个参与身份, 容器:将容器 box 变为弹性盒子称为Flex容器(flex container), 它的子元素A-E 便会成为容器成员 称为Flex项目(flex item)
    • 布局的首要重点得先弄懂什么为 主轴、交叉轴、起点
    • 对应容器和项目 都会有相应的属性去调整布局
    • 我们先从容器入手来看看弹性盒子会给我们带来怎样的属性
    属性介绍
    display设置盒子为弹性盒子 (flex、inline-flex), 这两就是之前盒子的 block 和 inline-block 特点, 区别是前者变为弹性盒子会改变子元素特性
    flex-direction决定主轴的方向
    flex-wrap如何换行
    justify-content主轴上的对齐方式
    align-items交叉轴上对齐方式
    align-content多根轴线的对齐方式,如果项目只有一根轴线,该属性不起作用

    容器: flex-direction属性

    • 设定主轴方向(主轴的垂直轴 就是 交叉轴)
    • 此属性记住两个主要值 row(水平方向排列)、 column(垂直方向排列), 后方带上-reverse 就表示反着来
    • 这个只带A-C三位兄弟写,就更方便看清楚

    x x x x

    容器: flex-wrap

    • 设置换行的方式
    • 这次会带上全部弟兄挤一挤, 这里我默认主轴设置的:row
    • flex-wrap: nowrap (不换行,也是默认值),图中可以看出本来是正方形的A-E元素被压成了长方形,因为不换行默认也不会去超出,而是会等分挤压元素的大小
      > x
    • flex-wrap: wrap ( 换行、第一行在上方 )
      > x
    • flex-wrap: wrap-reverse ( 换行、第一行在下方, 也就是代表是wrap的反向来 )
      > x

    容器:justify-content

    • 设定项目在主轴上的对齐方式
    • flex-start & flex-end代表的是主轴的起点对齐还是主轴的终点方向对齐
    • justify-content: flex-start 起点方向对齐、默认值
      > x
    • justify-content: flex-end 终点方向对齐, 因为我的起点方向是左侧,可以看到终点对齐就会是右侧
      > x
    • justify-content: center 居中对齐
      > x
    • justify-content: space-between 两端对齐,左右元素两端靠边对齐,剩余空间会等分给项目之间的间隔,项目之间的间隔会保持一致
      > x
    • justify-content: space-around 项目两侧间隔相等,仔细看下面的DE可以看出,项目中间的间隔会等于两侧的间隔相加, 因为项目的左右间隔会保持一致,例如左右10px的间隔,那么项目之间的间隔就会有20px
      > x

    容器:align-items

    • 设定项目在交叉轴上对齐方式
    • 因为此时我们的主轴属性为 row: 水平方向, 所以我们的交叉轴为垂直方向, 接下来我会让A,B,C三个元素出场,并给不同的身高来仔细看到交叉轴的对齐效果
    • align-items: flex-start 交叉轴起点对齐
      > x
    • align-items: flex-end 交叉轴终点对齐
      > x
    • align-items: center 交叉轴的中点对齐
      > x
    • align-items: stretch 对齐方式为交叉轴起点, 但与flex-start不同的是如果项目未设置高度,或者高度为auto 高度会铺满容器 , 我这里B元素高度设置为了auto
      > x
    • align-items: baseline 项目的第一行文字的基线对齐
      > x

    容器:align-content

    • 多条轴线的对齐方式
    • 如果项目只有一根轴线,没换行的那种该属性不起作用
    • 心细的应该能发现, 其实该属性和justify-content整体一致 只是justify-content代表主轴,
    • align-content: flex-start 与交叉轴起点对齐
      > x
    • align-content: flex-end 与交叉轴的终点对齐
      > x
    • align-content: center 交叉轴的中点对齐
      > x
    • align-content: space-between 交叉轴两端对齐
      > x
    • align-content: stretch 轴线占满整个交叉轴
      > x
    • align-content: space-around 轴线两侧间隔相等
      > x

    项目的属性

    • 基本为数字型,主要是项目之间如何排序和分配空间

    项目: order属性

    • 排序值,数字越小越靠前 (此处的靠前是指靠近主轴的起点)
    • 正常而言应该是ABCDE, 但我此刻修改一下他们的order值
      > x

    项目:flex-grow属性

    • 分配剩余空间,
    • 如果设置了margin,padding, border,width, 此属性分配的宽等于 会先减去盒子模型占的宽, 再去分配剩余的宽
    • 分配规则为 (容器的content宽度 - 项目的盒子模型宽度总和)/项目的flex-grow数值总和 = flex-grow:1 的宽度
    • 默认为0代表即便存在剩余空间也不放大, 如果设置了值那么存在剩余空间元素就会放大改变原有宽度
    • 首先我们看一个项目,容器宽为350px,项目100px, 我将 B的flex-grow设置为1, 其余A和C默认0不放大,那么效果便会是所有剩余空间被B分掉
      > x
    • 第二个效果, 将项目的宽取消掉 设置 A( flex-grow: 1 ), B( flex-grow: 2 ), C( flex-grow: 1 )
    • 代表我们将容器划分为了4份 B分了两份剩余空间, A一份剩余空间、C一份剩余空间
      > x

    项目: flex-shrink属性

    • 默认值为1, 定义缩小比例
    • 在项目空间不足时的缩小比例, 值越大压缩的越狠, 为0时代表不压缩, 此处设置C为0,C就没被压缩,其他的元素等比压缩
      > x

    项目: flex-basis属性

    • 定义多余空间分配前项目占据的主轴空间 (值为宽高同款设定)
    • 此处所有项目主轴空间为100px, 但我单独设定C的flex-basis为200px, 效果就会如下
      > x

    项目: align-self属性

    • 项目的对齐方式
    • 项目唯一一个不是做分配的值, 该值代表单独设定项目的交叉轴对齐方式
    • 此处我的容器高300px 默认对齐方式为 flex-start, 但我单独设定B为flex-end 就会呈现这种效果
      > x

    总结

    • 容器定义项目对齐的方式、轴方向、换行
    • 项目做空间的分配与排序
    • 下一篇弹性布局文章常见示例篇