关于负margin的问题

在学习CSS的时候遇到这样的问题。要想实现的效果是这样的:
图片描述

然后代码是这样的:

<!DOCTYPE html>
<html lang="en">
<head>
    <style>
    ul,li{
        margin: 0;
        padding: 0;
        list-style: none;
    }
    .ct {
        width: 640px;
        overflow: hidden;
        border: 5px solid #000 ;
        margin: 0 auto;
    }
    .ct>ul{
        margin-right: -20px;

    }
    .ct .item{
        float: left;
        width: 200px;
        height: 200px;
        margin-right:20px;
        margin-top:20px; 
        background: red;
    }
    </style>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div class="ct">
        <ul>
          <li class="item">1</li>  
          <li class="item">2</li>  
          <li class="item">3</li>  
          <li class="item">4</li>  
          <li class="item">5</li>  
          <li class="item">6</li>  
          <li class="item">7</li>  
          <li class="item">8</li>  
        </ul>
    </div>
</body>
</html>

我不懂的是对ul这个标签的处理,这个父容器的宽度是640px,方块的宽度是200px,再加上右margin的20px,这样两个方块占据的宽度就为440px了,还剩下200px,这时候给ul设置了margin-right:-20px为什么这里一行就可以容纳三个元素了?给ul设置样式不就相当于对ul里面的8个li设置了负margin了吗,这到底是什么原理?还有用浏览器的开发者工具检查第三个方块的时候可发现:
图片描述

这里第三个方块的右margin都跑到父容器的外边去了
这到底是什么原因呢?望解答。感激不尽~

阅读 3.1k
2 个回答

-------------------更新线开始---------------------

发现关于inline-block我想错了,inline-block只能显示两个是因为inline-block默认会有间隙,可以参考这篇文章:如何解决inline-block元素的空白间距。重新改下答案。

li元素inline-block之后,虽然ul还是660,但inline-block之间还有间隙,所以前两个占据的不止是440,而应该是448(chrome默认间隙为4)。而float之后,ul是660,且li之间没有间隙。就可以显示3个。

即使把.ct设置宽度为width: 300px;,只要ul宽度设置为660,而li仍然是float,一行也会显示3个。如下图:

综上,主要还是盒模型、float。

clipboard.png

-----------------更新线结束-----------------------

1、margin

margin不会继承,除非声明继承,如下,然后又存在先后覆盖的问题,所以得把你的margin-right:20px;注释掉,这样li元素margin就是-20px

.ct .item{
            margin-right: inherit;
            float: left;
            width: 200px;
            height: 200px;
            /*margin-right:20px;*/
            margin-top:20px;
            background: red;
        }
        

css后面的会覆盖前面的,下面代码得到的结果是20px,而不是0,这不是计算的关系。

.ct .item{
            margin-right:-20px;
            margin-right:20px;
        }

2、float

float布局会脱离正常的文档流。如果不用float,用display:inline-block,就只能容下两个方块,如下(主要还是浏览器的默认间隙)

.ct .item{
            display: inline-block;
            width: 200px;
            height: 200px;
            margin-right:20px;
            margin-top:20px;
            background: red;
        }

效果在这

clipboard.png

上面说得不够正确。能显示3个和你的ul的margin-right:-20px;有极大的关系。设置成-20使得ul宽度到了660,你把ul设成overflow:hidden就可以看出来。同时你的ct又是overflow:hidden,如果不是就会有滚动条。你把ul的margin-right改成-19也只会显示两个。所以能显示三个是正常的。只是可能不容易看出来。

接着说ul设置margin-right:-20px;使得ul宽度为660的问题,这是因为ul是一个block的布局,如果规定它的width是640px,那也会只显示两个。

给ul设置的margin属性并不能继承给其子元素,而给某元素设置负边距可以理解为变相的增加了宽度(不影响其实际宽度,像transform这种感觉)

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题