w3ctech

那些年我们一起经历过的float

浮动float的那些事

元素进行浮动后,display属性隐性变为inline-block

样式代码

<style type="text/css">  
    * {  
        margin: 0;
        padding: 0;
    }
    .myDiv1 {
        width: 300px;
        height: 200px;
        background: #ff0;
    }
    input[type="text"]:nth-of-type(1){

    }
    /*chrome中浏览器input默认样式*/
    input {
        -webkit-appearance: textfield;
        padding: 1px;
        background-color: white;
        border: 2px inset;
        border-image-source: initial;
        border-image-slice: initial;
        border-image-width: initial;
        border-image-outset: initial;
        border-image-repeat: initial;
        -webkit-rtl-ordering: logical;
        -webkit-user-select: text;
        cursor: auto;
    }
    input,
    textarea,
    keygen,
    select,
    button {
        margin: 0em;
        font: normal normal normal normal 13.3333330154419px/normal Arial;
        text-rendering: auto;
        color: initial;
        letter-spacing: normal;
        word-spacing: normal;
        text-transform: none;
        text-indent: 0px;
        text-shadow: none;
        display: inline-block;
        text-align: start;/*W3C中给出值left,right,center,justify,inherit*/
    }
    input:not([type]),
    input[type="email" i],
    input[type="number" i],
    input[type="password" i],
    input[type="tel" i],
    input[type="url" i],
    input[type="text" i] {
        padding: 1px 0px;
    }/*W3C给出input的type值button,checkbox,file,hidden,image,password,radio,reset,submit,text*/    
</style>

代码

<div class="myDiv1"></div><input type="text" name="userName"/>

可以清晰的看到div.myDiv1和input分别占两行,这是因为div.myDiv1为块级元素,默认会独占一行(ps:即使是设置width,也会独占一行,例如width:200px;有一种解释就是块级元素后面浏览器会自动添加<br/>,曾遇到一个坑,存在一个这样的情景:一个div#container里面包含rows=20,cols=10,总共200个float属性设置成left的div.children,假设每个div.children的width和height设置成30px,按照常理来说,div#container的height应该为600px,不考虑div#container的padding以及div.children的margin和padding,但是结果div#container的height比预想600px要高一些,经过分析发现,正是因为每个div后面的 <br/>标签(即使是display属性为inline-block,<br/>标签仍然存在),其实是一个空白字符,每个div都有默认的font-size,所以这些空白字符会占据一些位置,导致div#container的height比预想的结果要大,最后的解决方法是将div#container的font-size设置成0)

<div class="myDiv1" style="float:left;"></div><input type="text" name="userName"/>

我们可以清楚的发现div.myDiv1和input处于同一行(ps:inline-block和inline布局的规则是多个元素处于同一行,当一行放不下时,放不下的元素会自动换行,但是我发现

<span class="span1">内容很多...</span>

<span class="span2">内容很多...</span>

处于同一行,但是当它们宽度超过父类的宽度时,不会换行,只会出现x轴的滚动条(span1和span2没有样式,只是区分一下),求解释,但是我用input来实验,结果发现,出现自动换行,input的display:inline-block,而span的display:inline,当一行可以放置所有的元素时,第一个元素的margin-left相对于父类来说的,其它的元素都是相对于左边的兄弟来说的,如果设置值的话,自己以及右边的兄弟都会向右移动,不管display值,margin-left以及margin-right不会发生margin折叠,margin-top都是相对于父容器来说的,但是当一行不能放下所有的元素,不能放下的元素自动换行,此时该元素margin-top则是相对于自己上一行的兄弟来说,如果该兄弟设置了margin-bottom时,inline-block元素不会发生margin重叠,但是inline验证不了(上面提到inline元素不自动换行)),这就是为什么float可以解决margin重叠问题,如图所示:
image

两个块级元素(div1设置float:left)


<div class="div1" style="float:left;"></div><div class="div2"></div>

如图: image 会发现div2会占据div1的位置,div1会浮在div2的上面,给人一种div1是div2的子类的错觉,其实这对div2的真正的子类有影响的,div1会脱离文档流,div1的父类是body,div2的父类也是body,但是它们分别设置margin-top:10px;以及margin-top:20px;的情况
代码

<div class="myDiv1" style="float:left;margin-top:10px;"></div><div class="myDiv2" style="margin-top:20px;"></div>

如图:
image 其实浏览器解析下,div1成为了div2的"子类"(表现是这样,其实div1脱离文档流啦,真正的父类其实是body)
如果按照上面的说法,如果仅设置div2的margin-left属性,div1是否也跟着移动呢?
代码

<div class="myDiv1" style="float:left;"></div><div class="myDiv2" style="margin-left:20px;"></div>

如图:
image

在margin-left属性,浏览器解析正常,明白div1脱离文档流,真正的父类其实是body,所以当div2设置 margin-left:20px;时,其实对div1没有影响的
但是这种"伪子类"其实在有些情况下还是会造成影响的
代码

<div class="myDiv1" style="float:left;"></div><div class="myDiv2" style="">流浪大法师的梦想是成为一名合格的前端工程师,希望能够进奇舞团工作学习</div>

如图:
image
出现这种情况,其实是浏览器将div1作为div2的子类,而且div1的display属性隐性变成inline-block,div2里面的内容(文字)其实可以看作inline-block或者inline,所以当div2的文字和div1可以放置在同一行,就变成多个inline或者inline-block或者inline和inline-block混杂的情况,在这里就不赘述啦
当div2的内容太多话,文本内容会到div1的下方,和多个inline或者inline-block或者inline和inline-block混杂情况下不能放置同一行的情况相同,在这里就不赘述啦

一个块级元素和一个行内元素(div1设置float:left)

代码

<div class="myDiv1" style="float:left;"></div><span>hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world hello world </span>

行内元素内容太多的话,行内元素里面的内容会换行,行内元素会一直被撑大,依然是紧靠div1,符合多个inline或者inline-block或者inline和inline-block混杂的情况
如图:
image
行内元素内容真的是太多的话,会出现将div1包围的情况
如图:
image
其实也可以解释,因为span行内元素中每一行文本都可以看作inline-block,当一行文本内容前面没有其它的inline或者inline-block时,就会从头开始,所以看起来给人一种将div1包围的错觉
未完待续

w3ctech微信

扫码关注w3ctech微信公众号

共收到1条回复

  • float元素不与任何元素的外边距产生折叠

    回复此楼