Henry Henry
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)

Henry

小学生中的前端大佬
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)
  • HTML

  • CSS

    • css 编码指南
    • CSS3 的 calc 使用
    • 表格固定表头的几种方法
    • nth-child 和 nth-of-type 的区别
    • 修改浏览器默认滚动条
    • 为什么两个宽度为父元素一半的子元素会超出父元素
      • 问题
      • 探索
      • 原因
      • 解决
        • 删除 换行符 / tab(制表符)/ 空格
        • 使用 margin 负值
        • 让闭合标签吃胶囊
        • font-size:0
        • letter-spacing
        • word-spacing
        • 浮动
        • 其他成品方法
      • 参考资料
  • 页面
  • CSS
Henry
2018-06-12
目录

为什么两个宽度为父元素一半的子元素会超出父元素

让两个子元素各占父元素的一半, 每个人能想到的都是 display: inline-block; width: 50%; , 但实际上却并不会平分, 而是会上下排列, 这是怎么回事呢?

# 问题

话不多说, 先看代码:

<html>
  <head>
    <style type="text/css">
      .box1 {
        background: #f00;
        height: 50px;
      }

      .box {
        display: inline-block;
        width: 50%;
        height: 100%;
      }

      .box2 {
        background: #0f0;
      }

      .box3 {
        background: #00f;
      }
    </style>
  </head>

  <body>
    <div class="box1">
      <div class="box box2"></div>
      <div class="box box3"></div>
    </div>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

本来想让 box2 和 box3 各占 box1 的一半, 但 box3 却被 "挤下去了", 难道 50% + 50% > 100% ?

# 探索

既然被 "挤下去了", 那我宽度窄点怎么样?

.box3 {
  width: 45%;
}
1
2
3

果然 "上去了", 但中间的空隙是什么鬼?

# 原因

原来, 行内元素 (包括行内块元素) 之间的空隙, 是由于 换行符 / tab(制表符)/ 空格 等引起的

# 解决

# 删除 换行符 / tab(制表符)/ 空格

  1. 连成一行:

    <div class="box box2"></div><div class="box box3"></div>
    
    1

    很影响阅读

  2. 标签之间没有 "间隙"

    <div class="box box2">
    </div><div class="box box3"></div>
    
    1
    2

    或者

    <div class="box box2"></div
    ><div class="box box3"></div>
    
    1
    2

    看的有点别扭, 但确实好使

  3. 利用 HTML 注释

    <div class="box box2"></div><!--
    --><div class="box box3"></div>
    
    1
    2

    会增加代码量

# 使用 margin 负值

.box {
  margin-right: -4px;
}
1
2
3

margin 负值的大小与上下文的字体和文字大小相关, 并不一定是 -4px ; 间距对应大小值可以参考张鑫旭的 拜拜了, 浮动布局 - 基于 display:inline-block 的列表布局 (opens new window) 一文的 part 6

其计算程度之复杂, 以及最后一个元素多出的负 margin 值等问题, 这个方法不适合大规模使用.

# 让闭合标签吃胶囊

如下处理:

<div class="space">
  <a href="##"> 惆怅
  <a href="##"> 淡定
  <a href="##"> 热血 </a>
</div>
1
2
3
4
5

注意, 为了向下兼容 IE6/IE7 等喝蒙牛长大的浏览器, 最后一个列表的标签的结束(闭合)标签不能丢.

在 HTML5 中, 我们直接:

<div class="space">
  <a href="##"> 惆怅
  <a href="##"> 淡定
  <a href="##"> 热血
</div>
1
2
3
4
5

好吧, 虽然感觉上有点怪怪的, 但是, 这是 OK 的.

注: 使用这种方法的条件: 标签不能嵌套自身

如下面示例:

<div class="space">
  <a href="##"> 惆怅
  <a href="##"> 淡定
  <a href="##"> 热血 </a>
</div>

<div class="space">
  <span> 惆怅
  <span> 淡定
  <span> 热血 </span>
</div>

<div class="space">
  <p> 惆怅
  <p> 淡定
  <p> 热血 </p>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

审查元素:

可以看到, a 标签和 p 标签按照预期渲染, 而 span 元素却是嵌套的. 这是由于 a 标签和 p 标签不能包含自身, 所以遇到下一个和自身相同的标签后, 会自动闭合; 而 span 可以包含自身, 所以会一直嵌套下去

# font-size:0

.box1 {
  font-size: 0;
}

.box {
  font-size: 14px;
}
1
2
3
4
5
6
7

这个方法, 基本上可以解决大部分浏览器下内联元素之间的间距 ( IE7 等浏览器有时候会有 1 像素的间距).

# letter-spacing

.box1 {
  letter-spacing: -5px;
}

.box {
  letter-spacing: 0;
}
1
2
3
4
5
6
7

负值视具体浏览器而定, 但一般 -10 以下其兼容性上的差异就可以被忽略

# word-spacing

.box1 {
  word-spacing: -6px;
}

.box {
  word-spacing: 0;
}
1
2
3
4
5
6
7

一个是字符间距 ( letter-spacing ), 一个是单词间距 ( word-spacing ), 大同小异. 也是负值大到一定程度兼容性上的差异就可以被忽略

# 浮动

.box {
  float: left;
}
1
2
3

父元素要注意是否需要清除浮动带来的影响

# 其他成品方法

下面展示的是 YUI 3 CSS Grids (opens new window) 使用 letter-spacing 和 word-spacing 去除格栅单元见间隔方法(注意, 其针对的是 block 水平的元素, 因此对 IE8- 浏览器做了 hack 处理):

.yui3-g {
  letter-spacing: -0.31em;
  /* webkit */
  *letter-spacing: normal;
  /* IE < 8 重置 */
  word-spacing: -0.43em;
  /* IE < 8 && gecko */
}

.yui3-u {
  display: inline-block;
  zoom: 1;
  *display: inline;
  /* IE < 8: 伪造 inline-block */
  letter-spacing: normal;
  word-spacing: normal;
  vertical-align: top;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

以下是一个名叫 RayM (opens new window) 的人提供的方法:

li {
  display: inline-block;
  background: orange;
  padding: 10px;
  word-spacing: 0;
}

ul {
  width: 100%;
  display: table;
  /* 调教 webkit*/
  word-spacing: -1em;
}

.nav li {
  *display: inline;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 参考资料

  • 去除 inline-block 元素间间距的 N 种方法 (opens new window)

  • 行内元素产生水平空隙的原因及解决方案 (opens new window)

编辑 (opens new window)
#Css
上次更新: 5/27/2023, 1:02:05 PM
修改浏览器默认滚动条

← 修改浏览器默认滚动条

最近更新
01
version 1.15
07-01
02
version 1.14
06-27
03
version 1.13
06-27
更多文章>
Theme by Vdoing | Copyright © 2017-2023 HenryTSZ | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式