css-inline-block和float的布局两者择其一?

几个月前,带着不甘和忐忑毅然决然的在亚马逊离职了,当时不知道对我来讲是好是坏,如今看来,当初的选择仍是蛮不错的。感受在亚马逊的几个月貌似接触最多的就是wiki和tt了,怀着对技术热忱离开,拒绝了腾讯,搜狐和凤凰网,最后来到了经纬系下的一家创业公司,开启了创业潮!我的在title和technology两方面对比仍是更喜欢后者吧,反正还没毕业,路还长着呢,好了言归正传!!!css

inline-block属性:

最近和boss直聘的前端leader吃饭,说到了布局的问题,其实css布局仍是挺容易让人入坑的,由于不少页面的html/css的布局不合理就回致使整个页面要用不少js来弥补你样式的坑,而且极可能在不通设备下样式直接乱掉。而通常前端工程师最经常使用的布局是float布局,聊到这里,基本上咱们意见一致,那就是能用inline-block就尽可能少用float或position!!!缘由很简单,就是float高度塌陷有的时候会致命!!!html

下面咱们来讲一下inline-block的那些坑:

咱们来先写这样一段代码前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/hjk.css">
    <style>
        .inlineBlock{
            display: inline-block;
            width: 200px;
            height: 200px;
            background: red;
            border:1px solid #666;
        }
    </style>
</head>
<body>
    <div class='inlineBlock'></div>
    <div class='inlineBlock'></div>
</body>
<script>
</script>
</html>

咱们来看一下效果:git

我勒个去,中间的哪一个间距是什么鬼?chrome

咱们知道inline-block元素实际上是一个具备区块元素,又具备内敛元素的一个元素!!bootstrap

好绕:其实inline-block就是不占据一行的块状元素!前端工程师

那么咱们怎么去解决呢?其实解决的方法挺多,知道的空白的元素是inline-block默认的空格符,那么咱们能够这样解决dom

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/hjk.css">
    <style>
        .inlineBlock{
            display: inline-block;
            width: 200px;
            height: 200px;
            background: red;
            border:1px solid #666;
        }
    </style>
</head>
<body>
    <div class='inlineBlock'></div><div class='inlineBlock'></div>
</body>
<script>
</script>
</html>

看一下样式:布局

好了这个问题就解决了,其实还有别的写法好比说:学习

  <div class='inlineBlock'></div><!-- 
     --><div class='inlineBlock'></div>

或者说:

<div class='inlineBlock'>
    我是内容</div><div class='inlineBlock'>
    我是内容</div>

可是这种方法老是让人看着头疼,由于这个不符合正常html代码的书写,那么咱们可能从css上面来决解这种问题么?

首先咱们想到的确定是给第二个元素添加margin负,代码以下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/hjk.css">
    <style>
        .inlineBlock{
            display: inline-block;
            width: 200px;
            height: 200px;
            background: red;
            border:1px solid #666;
        }
        .div2{
            margin-left: -4px;
        }
    </style>
</head>
<body>
    <div class='inlineBlock div1'></div>
    <div class='inlineBlock div2'></div>
</body>
<script>
</script>
</html>

运行结果:

可是这种方法存在问题:

1.咱们布局确定不少元素,不可能每一个都添加margin负这样维护成本太大了

2.咱们线上代码若是压缩,那么咱们就不存在哪一个4px的问题了,那么咱们的margin负就回形成布局混乱!

哪么难道不能用css来解决这个问题么?

还有一种方法仍是这种方法也有缺点

咱们给元素加一个container而后设置font-size为0就能解决这个问题,而后根据咱们每一个布局模块想要的font-size在本身添加font-size

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/hjk.css">
    <style>
        .container{
            font-size: 0;
        }
        .inlineBlock{
            display: inline-block;
            width: 200px;
            height: 200px;
            background: red;
            border:1px solid #666;
            font-size: 12px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class='inlineBlock div1'></div>
        <div class='inlineBlock div2'></div>
    </div>
</body>
<script>
</script>
</html>

这样子咱们也能获得咱们想要的结果,可是其中利弊本身体会!

因此每一种方法都有优缺利弊,我的仍是喜欢注释法,压缩上线也不会有问题,也比较推荐这个!

好了咱们继续,下面若是咱们给div内部加文字会怎么样呢?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/hjk.css">
    <style>
        .container{
            font-size: 0;
        }
        .inlineBlock{
            display: inline-block;
            width: 200px;
            height: 200px;
            background: red;
            border:1px solid #666;
            font-size: 12px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class='inlineBlock div1'></div>
        <div class='inlineBlock div2'>我是内容</div>
    </div>
</body>
<script>
</script>
</html>

效果以下:

我勒个擦,我就加了个文字,这是什么鬼——,怎么莫名其表的还掉下来了?

其实这个问题主要的缘由是由于咱们默认的文字对齐是baseline,基线对齐,因此咱们的inline-block元素就会出现这样的问题!

咱们改一下html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/hjk.css">
    <style>
        .inlineBlock{
            display: inline-block;
            width: 200px;
            height: 200px;
            background: red;
            border:1px solid #666;
            font-size: 12px;
        }
    </style>
</head>
<body>
    <div>
        我是container内容
        <div class='inlineBlock div1'></div><!-- 
         --><div class='inlineBlock div2'>我是div2内容</div>
    </div>
</body>
<script>
</script>
</html>

效果以下:

也就是说咱们如今全部inline内容都是跟container的基线对齐的由于div2内部加入了inline,因此整个元素都掉了下来基线对齐!可是为何并非彻底的对齐呢?咱们如今来加入这样一行代码:

     .inlineBlock{
            line-height: 0;
        }

效果以下:

看到这里你应该明白了吧,inline-block的元素,受line-height和vertical-align两个元素的影响!(不明白vertical-align或二者的关系的同窗,建议先去学习一下)

那么到这里咱们的问题就好解决了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/hjk.css">
    <style>
        .inlineBlock{
            display: inline-block;
            width: 200px;
            height: 200px;
            background: red;
            border:1px solid #666;
            font-size: 12px;
            vertical-align: top;
        }
    </style>
</head>
<body>
    <div>
        我是container内容
        <div class='inlineBlock div1'></div><!-- 
         --><div class='inlineBlock div2'>我是div2内容</div>
    </div>
</body>
<script>
</script>
</html>

效果以下:

这样咱们就实现了top线对齐,问题圆满解决!

其实还有个容易的方法,只须要添加float,全部问题迎刃而解:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/hjk.css">
    <style>
        .inlineBlock{
            display: inline-block;
            width: 200px;
            height: 200px;
            background: red;
            border:1px solid #666;
            font-size: 12px;
            float: left;
        }
    </style>
</head>
<body>
    <div>
        <div class='inlineBlock div1'></div>
        <div class='inlineBlock div2'>我是div2内容</div>
    </div>
</body>
<script>
</script>
</html>

你看他俩靠的多近啊,尚未掉落的问题,可是由于float的高度塌陷问题又来了,刻刻~~~本身慢慢领悟!!

float布局

接下来咱们来看看float的问题,这里咱们用到了盒模型,建议基础很差的小伙伴学一学盒模型

其实float最开始出现就是为了实现文字环绕效果,float以后高度塌陷,因此文字会环绕这你float的元素!注意是文字环绕,不是元素环绕!可是由于float元素的出现咱们大多数都比较喜欢用float布局,float属性就这样子被滥用了,固然我也是其中的一员。虽然高度塌陷这个问题(不是bug)比较让人头疼,可是比起inline-block元素来讲,我仍是更喜欢float的布局方式!

首先咱们来讲一下一种总体的warp布局(这个和float无关),就拿咱们学校的官网举例- -:

这种布局(好比背景颜色想要#eee),首先的第一种想法确定是我先外层一个div,width为100%,而后内部div设置class为wrap,而后我给wrap一个固定的width,以后margin负居中,这种是人们最多见的,也是最经常使用的。可是这种方式我并不接受,第一外层div并无用出了设置了背景颜色,第二就是咱们margin负就必需要根据计算而来的margin负,若是改动width那么margin负也要跟着改!

我我的比较推崇padding方式来实现这个布局,既能减小没必要要的dom元素,也能避免margin带来的问题!

代码以下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        *{
            padding: 0;
            margin: 0;
        }
        .container{
            padding: 20px 40px 40px;
            height: 100px;
            background: #eee;
        }
    </style>
</head>
<body>
    <div class='container'>
        sdf
    </div>
</body>
</html>

效果以下:

咱们用padding来单体了以前的warp布局,以后咱们给container内部添加一下浮动元素

css:

     .fBox{
            width: 25%;
            height: 200px;
            float: left;
            box-sizing: border-box;
            border:1px solid #000;
        }

dom:把container替换成

  <div class='container'>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBoxc"></div>
    </div>

效果以下:

由于内部高度塌陷,因此float的元素并无撑开整个container,怎么解决这个问题呢?咱们首先想到的确定是clear:both;清除浮动

代码以下:

  <div class='container'>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBoxc"></div>
        <div style='clear: both;'></div>
    </div>

效果以下:

这个问题虽然解决了,可是存在不少问题。

首先从html的原则来讲咱们新增了一个空白div元素,这就违背了咱们坚守无用dom元素的原则了,其次咱们若是不少个浮动,那么咱们须要给不少container内部最后一行清除浮动,这样子整个页面代码会很混乱。

下面咱们来介绍第二种方法:

咱们去掉container的height高度添加overflow:hidden;

代码以下:

     .container{
            padding: 20px 40px 40px;
            background: #eee;
            overflow: hidden;
        }

 

 html:

       <div class='container'>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBoxc"></div>
    </div>

效果以下:

这个兼容性很是的好,并且确实可以撑起来整个container,可是存在很大的问题(本人就在这个属性栽倒过)

1.不能使用position超出尺寸的会被隐藏

2.若是布局已经内部float并不知道height有多大,千万不要使用,由于若是height比你的设备的height还要大的时候,每次滑动页面以前都会计算container的高度,因此也就是说滑动以前你须要点一下屏幕,他计算的事件虽然不少很短可是这个问题特别影响用户体验!

我曾经在学校给一家公司作活动需求,当时为了方便用的这个属性来兼容自动撑开container,当时也没有本身的手机作一下测试,由于项目赶的比较急,而后在chrome上面测了一下没问题就直接提交到git上了,结果当天晚上12点以前上线,公司测试并无测出咱们个overflow的问题,后来临近12点的时候在线下忽然测出了这个问题,以后为了兼容这个问题,我整个页面的布局所有大改,由于当时css比较渣,页面混用了float和position,而后overflow自适应,再加上页面比较复杂,因此我改页面改到凌晨2点办才修复这个bug,再加上当时ui那面也出了一点问题,因此整个活动延迟到次日中午12点上的线。沉痛的教训!!!

 

下面我说一下我最推荐的一种方式,也是如今最主流的方式,京东淘宝都在用这个来决解浮动问题!就是经过委元素来清除浮动

代码以下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        *{
            padding: 0;
            margin: 0;
        }
        .fBox{
            width: 25%;
            height: 200px;
            float: left;
            box-sizing: border-box;
            border:1px solid #000;
        }
        .container{
            padding: 20px 40px 40px;
            background: #eee;
        }
        .clearFix:after{
            content:'';
            clear: both;
            display: table;
        }
    </style>
</head>
<body>
    <div class='clearFix container'>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBoxc"></div>
    </div>
</body>
</html>

效果以下:

这样咱们就解决了浮动的问题,接下来咱们尝试一下根据不一样屏幕的尺寸来改变每一个li的width来实现移动端的自适应

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        *{
            padding: 0;
            margin: 0;
        }
        .fBox{
            width: 50%;
            height: 200px;
            float: left;
            box-sizing: border-box;
            border:1px solid #000;
        }
        @media (min-width: 992px){
            .fBox{
                width: 25%;
            }
        }
        @media (max-width: 750px){
            .fBox{
                width: 100%;
            }
        }
        .container{
            padding: 20px 40px 40px;
            background: #eee;
        }
        .clearFix:after{
            content:'';
            clear: both;
            display: table;
        }
    </style>
</head>
<body>
    <div class='clearFix container'>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBox"></div>
        <div class="fBoxc"></div>
    </div>
    <p>sdjfkjahskdfhjkhsdfhsdkfjhsdjkhf</p>
</body>
</html>

效果以下:

width:1200px

width:750px

width:600px

看到这个咱们可能给不一样的media里面添加不用的class设置不一样的width百分比,这样咱们只须要给一个元素添加这三个class就可以实现不用width尺寸的屏幕显示不用的布局!看到这里你有没有恍然大悟,没错bootstrap3的基本布局原理与不一样设备的class实现原理就是这样子设计的!

相关文章
相关标签/搜索