首页 文章

3个内嵌块div,正好宽度为33%,不适合父级

提问于
浏览
18

这是一个常见的问题,但我无法弄清楚它为什么会发生 .

我有一个父div,在div里面我有3个div,宽度设置为33%(确切地说,不是33.3%!)和 display: inline-block .

在Chrome中它运行良好,但在Mozilla和Opera中它没有(我还没有在IE中测试它) . 我认为问题可能出在算法浏览器用于从百分比计算像素大小的算法中 . 但是当我检查DOM指标时,我发现父亲的宽度是864px而孩子的宽度是285px(这是正确的:864 * .33 = 285.12) . 但为什么它不适合父母呢? 285 * 3 = 855,比父母的宽度小9px!

哦,是的,所有div的填充,边距和边框设置为0,DOM指标确认 .

7 回答

  • 38

    Whitespace in the HTML source code

    在HTML源代码中,当您有文本或图像行或 inline-block 元素时,如果它们之间有任何空格(空格,制表符或新行),则在它们之间会添加一个空格字符 . 页面呈现 . 例如,在以下HTML中,四个内容中的每一个之间都会出现一个空格:

    one
    two
    <img src="three.png"/>
    <span style="display: inline-block;">four<span>
    

    这对于文本行以及出现在文本行内的小图像或HTML元素非常有用 . 但是当 inline-block 用于布局目的时,而不是在文本段落中添加内容的方式,这成为一个问题 .

    Removing the extra space

    避免在 inline-block 元素之间添加额外的4px空间的最安全的跨浏览器方法是删除HTML标记之间的HTML源代码中的任何空格 .

    例如,如果你有一个带有3个浮动 li 标签的 ul

    <-- No space, tabs, or line breaks between </li> and <li> -->
    <ul>
        <li>...</li><li>...</li><li>...</li>   
    </ul>
    

    不幸的是,这会损害网站的可维护性 . 除了使代码不可读之外,它还严重损害了数据和格式的分离 .

    如果另一个程序员稍后出现并决定将每个 li 标记放在源代码中的单独行上(不知道为什么标记在同一行上,或者可能通过HTML Tidy运行它,甚至没有机会注意到任何相关的HTML评论),网站突然有一个格式错误,可能很难识别 .

    Consider floating elements instead

    空白行为强烈表明,将 inline-block 用于一般布局目的可能不适合将其用于除了在文本段的流内添加内容之外的任何内容 .

    另外,在某些情况下, inline-block 内容很难完全样式化和对齐,尤其是在旧版浏览器上 .

    Quick summary of other solutions

    • 将close标记放在与下一个打开标记相同的行上,它们之间没有空格 .

    • 使用HTML注释填充close标记和下一个打开标记之间的所有空格(如@Arbel建议的那样) .

    • 为每个元素添加负左边距(通常为-3px或-4px,基于字体大小) . 我不推荐这种特殊方法 .

    • 将容器元素的 font-size 设置为0或0.01em . 这在Safari 5中不起作用(不确定更高版本),它可能会干扰响应式设计网站,或任何使用 font-size 以外的 font-size 单位的网站 .

    • 使用JavaScript或jQuery从容器中删除仅空白文本节点 . 虽然元素之间仍然添加了空格,但这不仅仅是元素之间的空格 .

    • 为容器设置 letter-spacingword-spacing (如@PhillipWills建议的那样) . Further info . 这需要在网站上标准化 em 尺寸,这可能不是所有网站的合理选择 .

    • text-space-collapse: discard; 添加到容器(以前称为 white-space-collapse ) . 不幸的是,任何浏览器都不支持this CSS3 style,标准尚未完全定义 .

  • 1

    如果您不想弄乱HTML格式,例如将所有带有 inline-block 的元素写在一行中以便将来读取,并且除去它们之间添加的额外空白区域,你可以"comment"白色空间 .

    例如,在您的代码中,这将解决问题,它甚至可以使用33.3%而不是33%:

    .parent {
        width: 100%;
     }
    .child{
        display: inline-block;
        width: 33.3%;
    }
    

    / \

    <div class="parent">
           <div class="child">bla-bla1</div><!-- 
        --><div class="child">bla-bla2</div><!-- 
        --><div class="child">bla-bla3</div>
    </div>
    
  • -1

    内部div之间添加一个空格 . 有一些CSS伏都教来纠正这个问题:

    div {
        letter-spacing: -.31em;
        word-spacing: -.43em;
    }
    div div {
        letter-spacing: normal;
        word-spacing: normal;
    }
    

    当然,您可能更喜欢使用类或其他东西来区分父级和子级 .

  • 4

    添加 float:left;

    .parent{
        width: 100%
    }
    .child{
        float:left;
        display: inline-block;
        width: 33%
    
    }
    

    http://jsfiddle.net/H6Whc/1/

  • 4

    有没有人试过显示:表?如果这不是一个好主意,为什么不呢?这适用于所有现代浏览器,我将其测试到IE9 .

    .parent{  
        display: table;
        width: 100%;
    }
    .containers {
        box-sizing: border-box;
        border: 1px solid #000;
        height: 50px;
        width: 33.3%;
        display: table-cell;
    }
    
  • 2

    这是由许多评论和@Avin提到的,但删除 display: inline-block 并将其替换为 float: left .

    .parent{
        width: 100%
    }
    .child{
        float:left;
        width: 33%
    }
    
  • 6

    这是一个常见问题,但可以通过将 display: table CSS属性分配给父div来非常容易地进行排序 .

相关问题