乐趣区

浮动元素的介绍为什么后面元素不能设置margin值解决办法

层级结构

在我们写 html 文档的时候, 我们所创键的元素默认都是在文档流中排列, 那么有在文档流中就有脱离文档流. 我们的浮动和绝对定位, 固定定位就是让元素脱离文档流.
那么先.. 说说我们的层级结构吧: 按最底层到高层排列

  1. 块级元素 (block) 层级
    1. 背景颜色
    2. 背景图层
    3.border 边框
    4. 普通内容层
  2. float 浮动层
  3. inline-block/inline 文本
  4. position 定位层级

文档流的排列方式就是前面讲的 inline/block/inline-block 的特性
在我们用 word 文档的时候, 引入图片的时候会去选择 文字环绕图片的样式, 去更好的节省空间并且更加美观. 因此我们引入了浮动这一样式, 为的就是节约浏览器的空间. 但是, 后面慢慢的发现了 浮动样式的布局比 display:inline-block 更加方面, 因为 inline-blcok 的解析空格和基线对齐是很头疼的, 写一些小 demo 案例可能不会有那么大的感觉, 但是写一些稍微多的会发现 div 的嵌套也是很头疼的.
浮动. 好用是好用但是也会造成一些问题. 因为设置浮动的元素会半脱离文档流.

半脱离文档流

为什么说是版脱离文档流呢? 我们前面说到了层级结构, 元素浮动起来后, 我们可以理解为漂浮到了普通内容层, 为什么这么说呢? 我们设置浮动之后, 文字会识别到到浮动元素, 因此会造成前面元素浮动起来后 后面元素会跑到前面元素下面去但是文字还留在原来的位置上. 块元素是感受不到浮动层的元素, 但是 inline/inline-block 是可以感受到浮动层的, 也就造成了上面的现象.

浮动___块级划

浮动会将元素转化为块级元素, 但却不具有独占一行和父元素宽度 100% 的特性. 而是像 inline-block 一样由里面的内容撑开.
意思就是: 给 span 标签设置浮动之后, 你就可以给 span 便签设置宽高和上下margin padding.

浮动 — 带来的问题

浮动是好用, 但是同时也带来了些问题
就如前面说的, 块元素是感受不到浮动元素的. 因此 如果父元素是 block 属性的话, 那么就会造成高度塌陷.

高度塌陷

就是原本高度由子元素撑开的父元素, 这时候撑开他的子元素飘了, 那么就没人去撑开父元素的高度了, 父元素的高度发生了改变, 这个现象就叫高度塌陷.

怎么解决浮动带来的问题呢?

1. 父元素设置固定的宽高

浮动元素会造成高度塌陷, 是因为元素浮动之后没有内容去撑开父元素的自适应高度. 那么这时候如果我们给父元素设置一个固定高度, 就不会有高度塌陷这么个现象了.

2. 引发 bfc(border format context)

引发 bfc 的方法有很多, 具体使用是看哪种方法对页面造成的影响最小. 都是给父元素设置值

display:inline-block 等

可以理解为触发了 bfc.
同时还可以这么理解, 前面所说的行内元素和行内块元素是可以感受到浮动元素的, 那么父元素设置为行内块元素也同样能够感受到浮动的子元素的高度, 那么就不会造成高度塌陷
同样的可以设置成:table-cell、tabble-caption

设置 overflow 值

只要 overflow 值不为默认的 visible 就能够出发 bdc, 比如scroll, auto. 通常比较习惯使用overflow:hidden, 但也会造成一些内容被隐藏的问题.

设置 float 值

子元素悬浮了, 那么就把父元素也飘起来那么就在一个平面上了, 这时候就可以感受到子元素的高度了. 因此设置父元素的 float 值不为 none 就好了.

设置 position 值

既然 float 半脱离了文档流, 这时候父元素全脱离文档流的话层级更高, 因此也就能够感受到底层级的高度了. (别慌, 马上就介绍 position 定位).
这里要注意的是:position:static, position:relative 是不脱离文档流的, 因此要设置成position:absolute,position:fixed,position:sticky(sticky 要注意兼容性写法, 很多版本还不适用, 可以去 can i use 上查找).

清除浮动 clear:both

清除浮动本质上就是换行, 为什么这么说呢?
当给元素设置一个清楚浮动后, 这个元素会去感受前面浮动元素的高度大小, 然后自适应的调整了下自己的位置.

为什么 margin-top 有时候会失效?

有些人可能会发现 margin-top 有时候会失效. 其实这不是失效, 是找不到看齐的对象.
在试验的时候, 可能会发现有时候不管怎么设置上 margin 值, 这个元素都是不动如山.
比如下面这个情况, 有兴趣的同学可以自己动手调试代码, 代码如下,

.a{
            width: 100px;
            height: 100px;
            background-color: yellow;
            border: 1px solid black;
        }
        .b{
            width: 500px;
            height: 500px;
            background-color: lightblue;
            /* border: 1px solid ; */
            /* padding-top: 10px; */
            /* overflow: hidden; */
            /* display: inline-block; */
        }
        .c{
            width: 100px;
            height: 100px;
            background-color: orange;
            float:left;
            /* margin-top:100px; */
        }
        .d{
            width: 100px;
            height: 100px;
            background-color: green;
            clear:left;
            margin-top:400px;
        }
        /* .e{
            width: 100px;
            height: 100px;
        } */
<div class="a">
        </div>
        <div class="b">
            <!-- <div class="e"></div> -->
            <div class="c"></div>
            <div class="d"></div>
        </div>


绿色的 div 块元素已经设置的 margin-top:400px 但是为什么毫无反应.
悄悄地说其实我刚开始的时候也很懵逼, 然后就各种试, 结果就发现了.
因为橘色元素的浮动, 并且这个橘色元素的外边距和父元素合并了. 导致绿色元素找不到边 去算自己的 margin-top.
1. 那么解决父子外边距合并问题, 大家都知道可以设置padding,margin,overflow:hidden 或者设置 border 就好了. 设置之后绿色元素就会忽略浮动元素去调自己的 margin 值. 同时还要注意的是, 由于clear:left 的使用, 这时候的 margin 值只能比 clear:left 的默认值大, 也就是比浮动元素的高度值大.
2. 如果橘色浮动元素上面有另外一个元素且不浮动的话 (就叫 element- 1 吧) 的话, 那么这时候绿的方块的 margin-top 值就是跟着 element-1 的底部去调整自己的位置.

退出移动版