Flex布局-子项

弹性盒子是一种用于 按行 或 按列的一维布局方法.

元素可以膨胀以填充额外的空间, 也可以 收缩 以适应更小的空间.

flex 容器项重点

只是用表格进行排版而已, 横向内容无关联哈, 只是简要回忆一些前置知识.

重点 常用布局
flex-direction 内联和块的 水平垂直居中布局
flex-wrap / flex-flow 不定项居中布局
justify-content 均分列布局
align-items 子项分组布局

flex 子项重点

也是用表格来进行排版, 横向内容无关联哈.

重点 常用布局
flex-grow: 扩展比例 粘性页脚布局
flex-shrink 收缩比例 溢出项布局
flex-basis 及flex缩写 两列与三列布局
order 与 align-self 等高布局

子项-拓展比例

flex-row 默认值是 0, 表示布占用剩余空白间隙, 以扩展自己的宽度, 应用于当子项空间小于容器时.

  • flex-grow: 0 默认不占剩余空间
  • flex-grow: 1 占满剩余空间
  • flex-grow: 0.5 占满剩余空间的一半
  • flex-grow: 2 和 1 等价, 占满剩余空间

当为一个盒子的时候, 进行一波查看:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>子项: flex-grow</title>
  <style>
    .main {
      height: 300px;
      width: 500px;
      background-color: pink;
      display: flex;
    }

    .main div {
      width: 100px;
      height: 100px;
      background-color: skyblue;

      /* flex-grow: 0; 是默认值, 默认不占剩余空间 */

      /* 为 1 的时候, 就会占满全部剩余空间 */
      /* flex-grow: 1; */

      /* 为 0.5 时, 占满剩余空间的一半 */
      /* flex-grow: 0.5; */

      /* 当大于 1 时, 都会占满整个剩余空间 */
      flex-grow: 2;
    }

  </style>
</head>
<body>
  <div class="main">
   <div>1</div>
  </div>
</body>
</html>

当为多个子项的时候, 还是可以以 1 作为参考分割比, 其实就是对剩余空间的分配百分比计算.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>子项: flex-grow</title>
  <style>
    .main {
      height: 300px;
      width: 500px;
      background-color: pink;
      display: flex;
    }

    /* 第一个盒子占 200px 宽 */
    .main div:nth-of-type(1) {
      width: 200px;
      height: 100px;
      background-color: skyblue;

      /* 将剩下的 200px 都给它, 或者均分 */
      /* flex-grow: 1; */

      /* 分成 3份, 它占 2分, 则 200 * 2/3 = 166.7 */
      /* flex-grow: 2; */

      /* 不满足1的时候, 类似将剩余分成10份, 它占2, 另外一个占1, 剩余空间是7  */
      flex-grow: 0.2;
    }

    /* 第二个盒子占 100px 宽 */
    .main div:nth-of-type(2) {
      width: 100px;
      height: 100px;
      background: gold;

      /* 将剩下的 200px 都给它, 或者均分 200 */
      /* flex-grow: 1; */

      flex-grow: 0.1;
    }

    /* 剩下空间为:  500 - 100 - 200 = 200px */

  </style>
</head>
<body>
  <div class="main">
   <div>1</div>
   <div>2</div>
  </div>
</body>
</html>

子项-收缩比例

flex-shrink 默认值是 1, 表示当 flex 容器空间不足时, 元素的收缩比例, 应用于当子项空间大于容器时.

  • flex-shring: 1 默认收缩, 和容器一样, 子项不会溢出
  • flex-shrink: 0 不收缩, 子项正常溢出容器
  • flex-shrink: 2 大于1和等于1的效果是一致的, 子项不溢出

当为一个盒子的时候, 进行一波查看:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>子项: flex-shrink</title>
  <style>
    .main {
      height: 200px;
      width: 500px;
      background-color: pink;
      display: flex;
    }

    /* 让尺寸溢出父容器 */
    .main div {
      width: 600px;
      height: 100px;
      background-color: skyblue;

      /* flex-shring: 1; 自动收缩, 让子项和容器大小相同 */

      /* 为 0 时, 不收缩, 则就溢出父容器啦 */
      /* flex-shrink: 0; */

      /* 为 0.5 时, 收缩, 超出部分 100px 的一半. 还是会溢出  */
      /* flex-shrink: 0.5; */

      /*为 2 时, 即只要大于 1, 就和容器一样大小啦 */
      flex-shrink: 22;
    }

  </style>
</head>
<body>
  <div class="main">
   <div>1</div>
  </div>
</body>
</html>

多个盒子也是一样的, 同拓展一行, 也是对溢出空间结合子项权重进行收缩分配而已啦.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>子项: flex-shrink</title>
  <style>
    .main {
      height: 200px;
      width: 500px;
      background-color: pink;
      display: flex;
    }

    .main :nth-of-type(1) {
      width: 300px;
      height: 100px;
      background-color: skyblue;

      flex-shrink: 3;
    }

    .main :nth-of-type(2) {
      width: 400px;
      height: 100px;
      background-color: gold;

      flex-shrink: 2;
    }

    /* 
    总宽: 500; box1: 300; box2: 400
    总溢出: 300 + 400 - 500 = 200

    当 box1, box2 的 shrink = 1 时: 

    收缩值: 
    box1: 200 * (300 / (300 + 400)) = 200 * 3/7 = 85.7
    box2: 200 * 4/7 = 114.3
    
    当 box1-shrink = 3;  box2-shrink = 2时: 

    此时 box1: 300 * 3 = 900; box2: 400 * 2 = 800, 那一共就是 17 份
    收缩值: 
    box1: 200 * 9/17 = 105.9 
    box2: 200 * 8/17 = 94.1

    */

  </style>
</head>
<body>
  <div class="main">
   <div>1</div>
   <div>2</div>
  </div>
</body>
</html>

子项-初始尺寸

flex-basis 默认值是 auto, 指定了子项在主轴方向的初始大小.

比如, 当前为水平布局,  子项的 width: 200px;  height: 100px;   

然后, 当改为垂直布局,  子项的 width: 100px;  height: 200px

这样的转置的话, 就可以设置 `flex-basis: 200px 进行作用的.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>子项: flex-basis</title>
  <style>
    .main {
      width: 500px;
      height: 500px;
      background-color: pink;
      display: flex;

      /* flex-direction: column; */
    }
    
    .main div {
      width: 100px;
      height: 100px;
      background-color: skyblue;

      /* row 布局时, 覆盖 width;  column 时, 覆盖 height */
      flex-basis: 200px;
    }
  </style>
</head>
<body>
  <div class="main">
    <div></div>
  </div>
</body>
</html>

但在实践中, 似乎用得也不多.

子项-flex

flex 属性是 flex-grow, flex-shrink, flex-basis 的缩写, 咱最长用的一个写法就是 flex:1.

/* flex: 1 等同于: */

flex-grow: 1;    占满剩余空间
flex-shrink: 1;  默认收缩
flex-basis: 0%; 


/* flex: auto 等同于: */ 

flex-grow: 1;    占满剩余空间
flex-shrink: 1;  默认收缩
flex-basis: auto; 

/* 感觉还是直接写减少记忆点 */
flex: 1 1 auto;

就其实 flex: 1 基本就搞定啦!

剩下的两个属性 orderalign-self 也基本很少用.

order 可以用来指定某个子项的排序优先级; align-self 就跟 容器的 align-items 的对齐方式类似的.

用到的时候查一下就差不多啦, 不讲了.

应用-等高布局

当有多列排列时, 如果其中一列的内容比其他列的内容多时, 这些列依旧保持相同的高度.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>等高布局</title>
  <style>
    .main {
      width: 500px;
      background-color: pink;

      /* flex 布局, 子项两端对齐 */
      display: flex;
      justify-content: space-between;
    }

    .main div{
      width: 100px;
      background-color: skyblue;
    }

  </style>
</head>
<body>
  <div class="main">
    <div>
      <p>哈哈哈哈哈</p>
      <p>哈哈哈哈哈</p>
      <p>哈哈哈哈哈</p>
      <p>哈哈哈哈哈</p>
      <p>哈哈哈哈哈</p>
    </div>
    <div>
      <p>吃肉肉</p>
      <p>吃肉肉</p>
      <p>吃肉肉</p>
      <p>吃肉肉</p>
      <p>吃肉肉</p>
      <p>吃肉肉</p>
      <p>吃肉肉</p>
    </div>
  </div>
</body>
</html>

可以看到弹性布局, 子项默认就是等高的, 啥也不用做就实现啦!

但是如果要用 float 来进行布局, 那就需要先左浮动, 再右浮动, 再清除浮动, 然后再用一个撑开的技巧:

相互抵消, 撑出来.
margin-bottom: -2000px;
padding-bottom: 2000px;

算了吧, 还是 flex 一把梭.

应用-两列与三列布局

最常见于网站后台布局, 左侧是侧边栏菜单, 右侧是内容区, 或者最右侧还有辅助栏的三列布局.

其特点就是: 其中一列或两列是固定宽度, 中间的内容区域是根据屏幕自适应.

  • 需要固定的列给固定宽度
  • 内容区 flex-grow : 1; 占满剩余空间即可, 还自适应.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>两列布局</title>
  <style>
    body {
      margin: 0;
    }
    .main {
      height: 100vh;
      /* background-color: pink; */
      display: flex;
    }
    
    /* 左侧边栏固定 */
    .col1 {
      width: 250px;
      background: skyblue;
    }

    /* 第二列的内容区, 占满剩余空间即可 */
    .col2 {
      flex-grow: 1;
      background-color: #ccc;
    }

    /* 如需第三列, 则直接固定宽度就行啦 */
    .col3 {
      width: 250px;
      background-color: pink;
    }
  </style>
</head>
<body>
  <div class="main">
    <div class="col1">第一列</div>
    <div class="col2">第二列</div>
    <div class="col3">第三列</div>
  </div>
</body>
</html>

牛呀, 这个 flex 有点东西!

粘性页脚布局

主要是移动端用得比较多些, 关键是内容区用 flex-grow: 1 占满剩余空间;

  • 当内容区是不满一屏时, 页脚默认出现在可视区最底端;

  • 当内容过多超出时, 页脚会被内容区域挤压到最后去; (滚动条);

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>粘性页脚布局</title>
  <style>
    body {
      margin: 0;
    }

    .main {
      /* 可视区 100vh */
      min-height: 100vh;
      display: flex;
      flex-direction: column;
    }

     .main .header {
      height: 100px;
      background-color: pink;
     } 

     .main .content {
      /* 让内容区占满剩余空间, 即撑开内容区域 */
      flex-grow: 1;
     }

     .main .footer {
      height: 100px;
      background-color: skyblue;
     }

  </style>
</head>
<body>
  <div class="main">
    <div class="header"></div>
    <div class="content">
      <p>哈哈哈哈哈</p>
      <p>哈哈哈哈哈</p>
      <p>哈哈哈哈哈</p>
      <p>哈哈哈哈哈</p>
      <p>当内容超级多时, 页脚会自动被往下推</p>
    </div>
    <div class="footer"></div>
  </div>
</body>
</html>

溢出项布局

应用场景主要在移动端顶部菜单项, 当内容板块很多, 而可视区有限时, 通过滑动让溢出的项进入可视区.

直接用 flex + 子项 shrink: 0; 一步就做到位了.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>溢出项布局</title>
  <style>
    .main {
      height: 100px;
      background-color: pink;
      display: flex;
      align-items: center;
    }
    .main div {
      width: 200px;
      height: 100px;
      background-color: skyblue;
      margin-right: 10px;

      /* 让它可以溢出 */
      flex-shrink: 0;
    }
  </style>
</head>
<body>
  <div class="main">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
    <div>6</div>
    <div>7</div>
    <div>8</div>
  </div>
</body>
</html>

关于 flex 子项重点的东西也差不多到这里了.

posted @ 2024-05-18 10:47  致于数据科学家的小陈  阅读(73)  评论(0编辑  收藏  举报