为什么两个宽度为父元素一半的子元素会超出父元素
让两个子元素各占父元素的一半, 每个人能想到的都是 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>
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%;
}
2
3
果然 "上去了", 但中间的空隙是什么鬼?
# 原因
原来, 行内元素 (包括行内块元素) 之间的空隙, 是由于 换行符 / tab(制表符)/ 空格 等引起的
# 解决
# 删除 换行符 / tab(制表符)/ 空格
连成一行:
<div class="box box2"></div><div class="box box3"></div>
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看的有点别扭, 但确实好使
利用
HTML
注释<div class="box box2"></div><!-- --><div class="box box3"></div>
1
2会增加代码量
# 使用 margin
负值
.box {
margin-right: -4px;
}
2
3
margin
负值的大小与上下文的字体和文字大小相关, 并不一定是 -4px
; 间距对应大小值可以参考张鑫旭的 拜拜了, 浮动布局 - 基于 display:inline-block 的列表布局 (opens new window) 一文的 part 6
其计算程度之复杂, 以及最后一个元素多出的负 margin
值等问题, 这个方法不适合大规模使用.
# 让闭合标签吃胶囊
如下处理:
<div class="space">
<a href="##"> 惆怅
<a href="##"> 淡定
<a href="##"> 热血 </a>
</div>
2
3
4
5
注意, 为了向下兼容 IE6/IE7
等喝蒙牛长大的浏览器, 最后一个列表的标签的结束(闭合)标签不能丢.
在 HTML5 中, 我们直接:
<div class="space">
<a href="##"> 惆怅
<a href="##"> 淡定
<a href="##"> 热血
</div>
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>
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;
}
2
3
4
5
6
7
这个方法, 基本上可以解决大部分浏览器下内联元素之间的间距 ( IE7
等浏览器有时候会有 1
像素的间距).
# letter-spacing
.box1 {
letter-spacing: -5px;
}
.box {
letter-spacing: 0;
}
2
3
4
5
6
7
负值视具体浏览器而定, 但一般 -10
以下其兼容性上的差异就可以被忽略
# word-spacing
.box1 {
word-spacing: -6px;
}
.box {
word-spacing: 0;
}
2
3
4
5
6
7
一个是字符间距 ( letter-spacing
), 一个是单词间距 ( word-spacing
), 大同小异. 也是负值大到一定程度兼容性上的差异就可以被忽略
# 浮动
.box {
float: left;
}
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;
}
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;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 参考资料
- 01
- 搭配 Jenkins 实现自动化打包微前端多个项目09-15
- 02
- 自动化打包微前端多个项目09-15
- 03
- el-upload 直传阿里 oss 并且显示自带进度条和视频回显封面图06-05