float和inline-block的列表项错位问题

字数 305阅读 141

应用场景:房源(商品)列表

这种列表布局很场景。比如天猫,淘宝,京东等商品类网站,链家,58,赶集等房源类网站。大致效果如下图:

列表布局-0.png

一般我都会用float来实现,很简单。稍微加点点小需求,如果每个列表项的高度不定呢。比如下面这种:
列表布局-1.png

由于房源的地址,可能是一行,也可能是2行,甚至3行才能显示完整呢。
就会出现下面这种错位的情况:
列表布局-2.png

原因:float布局,它具有破坏性,float元素会脱离文档流。它的排列方式有点像肥皂泡效果。
解决方案:用display: inline-block。(当然如果这种方式碰到空字符占位问题,可以用letter-spacing: -0.5em;来处理。)代码如下:

<html>
<head>
    <meta  charset="utf-8">
    <title>列表项错位问题</title>
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        .hidden{
            display: none;
        }
        ul{
            list-style: none;
        }
        .clear:after{
            content: '';
            display: block;
            width: 0;
            height: 0;
            clear: both;
        }
        /*demo1*/
        .demo1 {
            margin: 20px auto;
            padding: 15px 0 0;
            width: 470px;
            outline: 1px solid #f00;
        }
        .demo1 li{
            /*float: left;*/
            display: inline-block;/*关键代码*/
            margin-left: 20px;
            margin-bottom: 15px;
            width:  130px;
            height:  100px;
            background: #2196F3;
        }
        .demo1 li.large{
            height: 130px;
        }
    </style>
</head>
<body>

<div class="demo1">
    <ul class="clear">
        <li>列表项11</li>
        <li class="large">列表项22</li>
        <li>列表项33</li>
        <li>列表项44</li>
        <li>列表项55</li>
        <li>列表项66</li>
        <li>列表项77</li>
        <li>列表项88</li>
    </ul>
</div>

</body>
</html>

应用场景:带排序功能的房源(商品)列表

在这里,我碰到的另外一个问题,让我加深了对float元素的特性的理解。如图:


列表布局-3.png

当时做的时候,出现了下面这种错位情况:


列表布局-4.png

列表中,无论我用float还是inline-block,仍旧这样。后来才发现,是因为排序栏,用了float,列表用了margin-top负数,导致列表和排序栏之间有重叠,也就是列表跟用了float的那块内容有重叠就会被挤下去。inline-block会整块被挤下去,就像上图那样;而float只是被挤下去重叠那部分。


列表布局-5.png

代码附上,可自行去验证:

<html>
<head>
    <meta  charset="utf-8">
    <title>列表项错位问题</title>
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        ul{
            list-style: none;
        }
        .clear:after{
            content: '';
            display: block;
            width: 0;
            height: 0;
            clear: both;
        }
        /*demo2*/
        .demo2 {
            margin: 20px auto;
            width: 470px;
            outline: 1px solid #f00;
        }
        /*排序*/
        .top {
            background: #efd68a;/*做标识用,方便查看列表和排序栏直接的交叉重叠部分*/
            height: 40px;
        }
        .top .sort{
            float: right;
        }
        .top .sort a{
            height: 40px;
            line-height: 40px;
        }
        .con{
            margin-top: -10px;
            padding: 0 0 15px;
        }
        /*列表*/
        .demo2 ul{
            margin-top: -15px;
        }
        .demo2 li{
            /*float: left;*/
            display: inline-block;
            margin-top: 15px;
            margin-left: 20px;
            width:  130px;
            height:  100px;
            background: #2196F3;
        }
        .demo2 li.large{
            height: 130px;
        }

    </style>
</head>
<body>
<div class="demo2">
    <div class="top clear">
        <div class="sort">
            <a href="#">最新 -</a>
            <a href="#">面积 ↓</a>
            <a href="#">价格 ↑</a>
        </div>
    </div>
    <div class="con">
        <ul class="clear">
            <li>列表项11</li>
            <li class="large">列表项22</li>
            <li>列表项33</li>
            <li>列表项44</li>
            <li>列表项55</li>
            <li>列表项66</li>
            <li>列表项77</li>
            <li>列表项88</li>
        </ul>
    </div>
</div>
</body>
</html>

解决方式:别让下面的列表跟上面用了float排序栏的重叠就行。将排序栏的float改成position: absolute;,或列表不用margin-top负数。

推荐阅读更多精彩内容