CSS3 之 flex:1;margin:auto;overflow:hidden ; BFC

409 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

今天在了解flex布局样式的时候,看到讲解老师写了个flex:1,然后就比较好奇这个到底做了哪些,加上 margin:auto 为何能实现居中overflow:hidden为何能实现BFC 一起总结学习一下。

flex

Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。设为Flex布局以后,子元素的floatclearvertical-align属性将失效。

flex有很多有效的布局样式,本文主要了解一下 flex:1做了什么,代表了什么。flex:1从效果来看可以自动填充满剩余空间。

我放了三个盒子,先看一下父盒子设置了flex:1。

image.png

再看看子盒子没有设置flex:1的情况 image.png 再看看 flex:1 1 0;

image.png

从上面可以看出,flex:1就是等于 flex:1 1 0。那么1 1 0 三个参数代表了什么呢?

flex:1即

    flex-grow:1;
    flex-shrink:1;
    flex-basis:0;

flex-grow定义项目的的放大比例;默认为0,即使存在剩余空间,也不会放大;flex-grow为1:等分剩余空间(自动放大占位)
flex-shrink定义项目的缩小比例;默认为1,即 如果空间不足,该项目将缩小;当空间不足时,缩小的比例相同;
flex-basis定义在分配多余空间之前,项目占据的主轴空间(main size),浏览器根据此属性计算主轴是否有多余空间。

因此,当flex为一个非负数字n:该数字为flex-grow的值,

flex:n;就是指

   flex-grow:n;
   flex-shrink1flex-basis0

margin:auto

margin的auto属性的作用是用来分配剩余空间,所以对于有剩余空间的元素才有效(块及元素)。比如图片设置margin: 0 auto是无效的,因为图片是内联元素,不是占一整行,没有剩余空间。
填充规则

(1) 如果一侧定值,一侧auto,则auto为剩余空间大小\

    .father {
      width: 300px;
      background-color: red;
    }

    .son {
      width: 200px;
      height: 120px;
      margin-right: 80px; 
      margin-left: auto;
      background-color: pink;
    }

image.png
左边距是20px,右边距是80px。这里son宽度是200px,容器是300px,总剩余空间大小是100px,其中margin-right使用了80px,那么margin-left的‘auto’计算值就是剩余的20px了 (2) 如果两侧均是auto,则平分剩余空间。

        .father {
              width: 300px;
              height: 150px;
              background-color: red;
              position: relative;
            }

        .son {
          position: absolute;
          top: 0;
          right: 0;
          bottom: 0;
          left: 0;
          width: 200px;
          height: 100px;
          background-color: white;
          margin: auto;
        }

image.png
当父元素、子元素宽高都设置为固定值的时候,设置margin:auto即可实现上下居中,左右居中效果。
注意:auto在浮动,内联和绝对元素中不起作用。

overflow:hidden

先了解下常见的定位方案,定位方案是控制元素的布局,有三种常见方案:

  • 普通流 (normal flow)

    在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行,除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。

  • 浮动 (float)

    在浮动布局中,元素首先按照普通流的位置出现,然后根据浮动的方向尽可能的向左边或右边偏移,其效果与印刷排版中的文本环绕相似。

  • 绝对定位 (absolute positioning)

    在绝对定位布局中,元素会整体脱离普通流,因此绝对定位元素不会对其兄弟元素造成影响,而元素具体的位置由绝对定位的坐标决定。

BFC 即 Block Formatting Contexts (块级格式化上下文),它属于上述定位方案的普通流。 浮动元素会脱离文档流(绝对定位元素也会脱离文档流),导致无法计算准确的高度,这种问题称为高度塌陷

BFC布局规则:

  1. 内部的Box会在垂直方向,一个接一个地放置。
  2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。
  3. 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  4. BFC的区域不会与float box重叠。
  5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  6. 计算BFC的高度时,浮动元素也参与计算

触发BFC方法

  • html根元素
  • 浮动元素:float 除 none 以外的值
  • 绝对定位元素:position (absolute、fixed)
  • display 为 inline-block、table-cells、flex
  • overflow 除了 visible 以外的值 (hidden、auto、scroll)

那么为什么overflow会创建BFC,先来看margin合并问题来理解:

    .bro1 {
      width: 200px;
      height: 200px;
      background: gray;
      margin-bottom: 30px;
    }
    .bro2 {
      width: 200px;
      height: 200px;
      background: pink;
      margin-top: 20px;
    }

两个上下排列的盒子,margin分别为30px、20px,但是最后实际边距只有30px,大的margin把小的margin合并了。

image.png
这些元素(包括兄弟、父子元素等)之间之所以会发生margin合并,是因为它们属于同一个BFC。 那么加上取消BFC的overflow:hidden之后呢

image.png

现在的边距就是我们想要的结果了。overflow会让两个盒子处于不同的BFC。 即"overflow:hidden"可以清除包含块内子元素的浮动的影响。BFC布局规则:计算BFC的高度时,浮动元素也参与计算。因此,父元素在计算其高度时,加入了浮动元素的高度,“顺便”达成了清除浮动的目标,所以父元素就包裹住了子元素。

除了设置"overflow:hidden",还可以设置"display:inline-block"、"position:absolute"、"float:left"等方式创建一个BFC。