• Flex布局


    在介绍Flex布局之前,先简述一下display属性。因为涉及到了 display: flex。详细介绍参考 https://developer.mozilla.org/en-US/docs/Web/CSS/display

    display 属性是使用关键字值指定的。关键字值分为六个值类别:

    .container {
    display: [ <display-outside> || <display-inside> ] | <display-listitem> | <display- internal> | <display-box> | <display-legacy> ;
    }
    • display-outside:这些关键字指定元素的外部显示类型,本质上是元素在流布局中的作用。

      • block:该元素生成一个块元素框,在正常流动中时在元素之前和之后都产生换行符。

      • inline:元素会生成一个或多个内联元素框,这些框不会在自身之前或之后产生换行符。在正常流动中,如果有空间,则下一个元素将在同一行上。

      • run-in:元素生成一个插入框。如果定义为display: run-in box 的元素的相邻同级 是一个block box,则该run-inbox成为其后的block box的第一个内联框。

    • display-inside:这些关键字指定元素的内部显示类型。

      • flow、flow-root、table、flex、grid、ruby

    因此display属性值不仅有 block、inline、inline-block,还有flex。

    Flex 布局

    布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。2009年,W3C 提出了一种新的方案----Flex 布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。详细介绍参考阮一峰老师的教程。 http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

    1. Flex布局是什么

    Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。

    两个重要的概念:

    (1)开启 flex 布局的元素叫做 flex container(容器)

    (2)flex container 里面的直接子元素叫做 flex items(项目)

    设置 display 属性为 flex 或者 inline-flex 都可以成为 flex container:

    (1)flex:flex container 以 block-level 形式存在

    (2)inline-flex:flex container 以 inline-level 形式存在

    // html:
    <div class="box">
        <div></div>
        <div></div>
        <div></div>
    </div>
    <strong>strong是行内元素</strong>
    
    // css:
    <style>
        .box {
          width: 300px;
          height: 300px;
          background-color: pink;
          /* display: flex; */
          display: inline-flex
        }
    </style>

    Webkit 内核的浏览器,必须加上-webkit前缀。

    .box{
    display: -webkit-flex; /* Safari */
    display: flex;
    }

    注意,设为 Flex 布局以后,子元素的floatclearvertical-align属性将失效。

    2. 基本概念

    采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。

    容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)

    主轴的开始位置(与边框的交叉点)叫做 main start,结束位置叫做 main end

    交叉轴的开始位置叫做 cross start,结束位置叫做 cross end

    项目默认沿主轴排列。单个项目占据的主轴空间叫做 main size,占据的交叉轴空间叫做 cross size

    3. 容器的属性

    所有的flex布局必须把父元素的display设置成flex,才能够使用flex布局。

    以下6个属性设置在容器上。

    • flex-direction

      • 该属性决定主轴的方向(即项目的排列方向)。有如下属性值:

      • row(默认值):主轴为水平方向,起点在左端。

      • row-reverse:主轴为水平方向,起点在右端。

      • column:主轴为垂直方向,起点在上沿。

      • column-reverse:主轴为垂直方向,起点在下沿。

       

    • flex-wrap

      • 默认情况下,项目都排在一条线("轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。

      • nowrap(默认):不换行。

      • wrap:换行,第一行在上方。

      • wrap-reverse:换行,第一行在下方。

       

    • flex-flow

      • 该属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap

       

    • justify-content

      • 定义了项目在主轴上的对齐方式。有如下属性值:

      • flex-start(默认值):左对齐

      • flex-end:右对齐

      • center: 居中

      • space-between:两端对齐(对准边线),项目之间的间隔都相等。

      • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

      • space-evenly:均匀排列每个元素,每个元素之间的间隔相等。

       

    • align-items

      • 定义项目在交叉轴上如何对齐。有如下属性值:

      • stretch(默认值):如果项目未设置高度或设为auto,则项目将占满整个容器的高度。
      • flex-start:交叉轴的起点对齐。

      • flex-end:交叉轴的终点对齐。

      • center:交叉轴的中点对齐。

      • baseline: 项目的第一行文字的基线对齐。

    • align-content

      • 定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

      • flex-start:与交叉轴的起点对齐。

      • flex-end:与交叉轴的终点对齐。

      • center:与交叉轴的中点对齐。

      • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。

      • space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。

      • stretch(默认值):轴线占满整个交叉轴。

     

    4. 项目的属性

    以下6个属性设置在项目上。

    • order

      • 定义项目的排列顺序。数值越小,排列越靠前,默认为0。

    • flex-grow

      • 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

      • 如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。

    • flex-shrink

      • 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

      • 如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。负值对该属性无效。

    • flex-basis

      • 定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。它可以设为跟widthheight属性一样的值(比如350px),则项目将占据固定空间。

    • flex

      • 它是flex-grow, flex-shrinkflex-basis的简写,默认值为0 1 auto。后两个属性可选。建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

      • 该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。

    • align-self

      • 允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch

      • align-self: auto | flex-start | flex-end | center | baseline | stretch;

      • 该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

    5. 骰子的布局(详细介绍参考上述提供网站)

    6. 网格的布局

    (1) 基本网格布局

    最简单的网格布局,就是平均分布。在容器里面平均分配空间,跟骰子布局很像,但是需要设置项目的自动缩放。

     

     关于 flex: 1 的相关说明:(参考https://www.cnblogs.com/zhus/p/7161702.html

    flexflex-growflex-shrinkflex-basis的缩写。故其取值可以考虑以下情况:

    • flex 的默认值是 0 1 auto。由于这里flex-grow是0,所以即使存在剩余空间,也不放大。

    • flex 取值为 none,计算值为 0 0 auto。即如果存在剩余空间,不放大。若空间不足,该项目也不缩小。
    • flex 取值为 auto,计算值为 1 1 auto。即如果存在剩余空间,会放大。若空间不足,该项目会缩小。

    • flex 取值为一个非负数字,则该数字为 flex-grow 值,flex-shrink 取 1,flex-basis 取 0%
    • flex 取值为两个非负数字,则分别视为 flex-growflex-shrink 的值,flex-basis 取 0%

    下面举例说明:

    <div class="parent">
      <div class="item-1"></div>
      <div class="item-2"></div>
      <div class="item-3"></div>
    </div>

    <style type="text/css">
      .parent {
          display: flex;
          600px;
      }
      .parent > div {
          height: 100px;
      }
      .item-1 {
          140px;
          flex: 2 1 0%;
          background: blue;
      }
      .item-2 {
          100px;
          flex: 2 1 auto;
          background: darkblue;
      }
      .item-3 {
          flex: 1 1 200px;
          background: lightblue;
      }
    </style>
    • 主轴上父容器总尺寸为 600px

    • 子元素的总基准值是:0% + auto + 200px = 300px,其中

      - 0% 即 0 宽度
      - auto 对应取主尺寸即 100px
    • 故剩余空间为 600px - 300px = 300px

    • 伸缩放大系数之和为: 2 + 2 + 1 = 5

    • 剩余空间分配如下:

      - item-1 和 item-2 各分配 2/5,各得 120px
      - item-3 分配 1/5,得 60px
    • 各项目最终宽度为:

      - item-1 = 0% + 120px = 120px
      - item-2 = auto + 120px = 220px
      - item-3 = 200px + 60px = 260px
    • 当 item-1 基准值取 0% 的时候,是把该项目视为零尺寸的,故即便声明其尺寸为 140px,也并没有什么用,形同虚设

    • 而 item-2 基准值取 auto 的时候,根据规则基准值使用值是主尺寸值即100px, 故这100px不会纳入剩余空间

    (2) 百分比布局

    <style>
        .Grid {
          display: flex;
          background-color: pink;
         800px;
        }
        .Grid-cell {
          flex: 1;
        }
        .Grid-cell:nth-child(1) {
           flex: 0 0 50%;
        }
    
        .Grid-cell:nth-child(2) {
           flex: 0 0 30%;
          background-color: purple;
        }
    
        .Grid-cell:nth-child(3) {
           flex: 0 0 10%;
           background-color: blue;
        }
    
      </style>
    </head>
    <body>
      <div class="Grid">
        <div class="Grid-cell">盒子1</div>
        <div class="Grid-cell">盒子2</div>
        <div class="Grid-cell">盒子3</div>
      </div>
    </body>

    这里主要讨论以下 flex-basis 的取值情况:

    • auto:首先检索该子元素的主尺寸,如果主尺寸不为 auto,则使用值采取主尺寸之值;如果也是 auto,则使用值为 content

    • content:指根据该子元素的内容自动布局。有的用户代理没有实现取 content 值,等效的替代方案是 flex-basis 和主尺寸都取 auto

    • 百分比:根据其包含块(即伸缩父容器)的主尺寸计算。如果包含块的主尺寸未定义(即父容器的主尺寸取决于子元素),则计算结果和设为 auto 一样。

     

    (3)圣杯布局

    <style>
        .HolyGrail {
          display: flex;
          /* min-height: 100vh; */
          flex-direction: column;
          width: 500px;
          height: 500px;
          background-color: pink;
        }
    
        header,
        footer {
          flex: 1;
          background-color: purple;
        }
    
        .HolyGrail-body {
          display: flex;
          flex: 2;
        }
    
        .HolyGrail-content {
          flex: 1;
          background-color: blue;
        }
    
        .HolyGrail-nav,
        .HolyGrail-ads {
          /* 两个边栏的宽度设为 30% 空余部分会由 HolyGrail-content补齐*/
          flex: 0 0 30%;
        }
    
        .HolyGrail-nav {
          /* 导航放到最左边 */
          order: -1;
        }
    
      </style>
    
    
    <body>
      <div class="HolyGrail">
        <header>header</header>
        <div class="HolyGrail-body">     
          <nav class="HolyGrail-nav">left</nav>
          <main class="HolyGrail-content">center</main>
          <aside class="HolyGrail-ads">right</aside>
        </div>
        <footer>footer</footer>
      </div>
    </body>

     (4)输入框的布局

    我们常常需要在输入框的前方添加提示,后方添加按钮。如下图效果:

    <style>
        .InputAddOn {
          display: flex;
        }
    
        .InputAddOn-field {
          flex: 1;
        }
      </style>
    
    
    <body>
      <div class="InputAddOn">
        <span class="InputAddOn-item">...</span>
        <input class="InputAddOn-field">
        <button class="InputAddOn-item">...</button>
      </div>
    </body>

     (5)悬挂式布局

    有时,主栏的左侧或右侧,需要添加一个图片栏。如下图效果:

    HTML代码如下:
    <div class="Media">
      <img class="Media-figure" src="" alt="">
      <p class="Media-body">...</p>
    </div>
    CSS代码如下:
    .Media {
      display: flex;
      align-items: flex-start;  /* 定义代码在交叉轴的起点对齐 */
    }
    
    .Media-figure {
      margin-right: 1em;
    }
    
    .Media-body {
      flex: 1;
    }
     

     

    (6)固定的底栏

    有时,页面内容太少,无法占满一屏的高度,底栏就会抬高到页面的中间。这时可以采用Flex布局,让底栏总是出现在页面的底部。

    HTML代码如下:
    <body class="Site">
      <header>...</header>
      <main class="Site-content">...</main>
      <footer>...</footer>
    </body>
    
    CSS代码如下:
    .Site {
      display: flex;
      min-height: 100vh;
      flex-direction: column;
    }
    
    .Site-content {
      flex: 1;  /* 由于flex-grow默认为0,将中间部分设置为1,若存在剩余空间会放大 */
    }

     

    (7)流式布局

    每行的项目数固定,会自动分行。

    CSS的写法如下:
    .parent {
       200px;
      height: 150px;
      background-color: black;
      display: flex;
      flex-flow: row wrap;
      align-content: flex-start;
    }
    
    .child {
      box-sizing: border-box;
      background-color: white;
      flex: 0 0 25%;
      height: 50px;
      border: 1px solid red;
    }
  • 相关阅读:
    学习OSGI---建项目,运行配置
    MongoDB 安装
    利用 ^ 异或运算符 进行交换(不需要第三方变量)
    2019HDU暑期多校训练-1004equation-方程求解
    HDU 4417-Super Mario-线段树+离线
    HDU 3333-Turing Tree-线段树+离散+离线
    POJ 2528-Mayor's posters-线段树+离散化
    POJ 2631-Roads in the North-树的直径
    POJ 2299-Ultra-QuickSort-线段树的两种建树方式
    noip2009最优贸易——spfa
  • 原文地址:https://www.cnblogs.com/BAHG/p/12770492.html
Copyright © 2020-2023  润新知