浮动 二 文字围绕现象 (上)

前段时间偷懒了好久.....内心很不安,我要加快速度了,吼吼吼

今天来说说float box的文字围绕现象。

下面的排版,想必从事前端开发的童鞋都很熟悉吧。

文字很配合的围绕在图片旁边,没有上浮,也没有下移,这究竟是为什么呢?让我们来一探到底吧!

围绕对象分析

我们常常看到一堆文字围绕着float box,大家有没有想过这些文字对应的是哪种box ? 要知道,网页都是由css box 拼成的!


根据普通流,浮动及绝对定位这三种定位,可知,box有三类:普通流中的box 、 float box 及 absolutely positioned box,而普通流中的box又分:inline box( 看第18条), 非inline box的inline-level box( 看第20条), block-level box( 看第21条)。试想下,如果这些box均包含文字,这些文字都可以围绕在float box旁边吗?

非也!

首先,排除absolutely positioned box。因为在定位机制中,absolutely positioned box级别高于float box,一旦box为absolutely positioned,则float属性值不管人为设置成什么都会被解析为none。

其次,排除float box。所有float box均会尽可能的向左或向右浮动,不可能围绕在某个float box旁边,当然,几个float box并行排列的情况是有的,但不能算是围绕。

最后,剩下的皆有可能。这包括inline box, 非inline box的inline-level box, block-level box。

围绕机制详解

我们知道float box是先出现在普通流中,然后再脱离普通流向左或向右浮动。它的行为类似于非inline box的inline-level box,只不过它具有浮动功能,并且可以与普通流中的任意box并行排列。这种并行排列造就了围绕现象!

当然,对于不同类型的box,围绕过程却是各有各的风采!

inline box

这个box比较特殊,它是以单个文字的形式参与到inline formatting context中的。什么是单个文字,"Oh, my god"不是单个文字,"Oh"是单个文字。这种特殊的参与形式决定了inline box可以跟随containing block(看第11条)的宽度变形,以"<span>Oh, my god</span>"为例,变化如下:

知道了这些,我们就好理解inline box是如何去包围的了。

例一 inline box在float box之前

<html>
  <head>
  <style type="text/css">	
	.parent{
		width:500px;
		height:120px;
		margin:20px auto 0;
		padding:10px;
		line-height:30px;
		font-family:"Times New Roman",Georgia,Serif;
		border:solid 2px rgba(247, 79, 79, 0.56);
	}
	.float-child{
		width:100px;
		height:50px;
		float:left;
		margin-right:10px;
		box-sizing:border-box;
		background:rgba(247, 79, 79, 0.56);
	}	
  </style>
  </head>
<body>
  <div class='parent'>
    <span>I'm inline element. I'm inline element. I'm inline element. I'm inline element. I'm inline element.</span>
    <div class='float-child'>
</div>
  </div>
</body>
</html>复制代码

在浏览器上测试如下:

因为inline box在float box之前,故渲染的时候它依然在前面,每个line box(看第16条)排满文字后,后面的文字自动排在下一个line box中,直至inline box中的文字都被排完。那么,就存在最后一个line box占不满一整行的情况。等到放置float box时,秉着“尽可能高”的原则,如果line box留下的横向空间足以放置float box,float box就会与最后一个line box同行,并按float属性指定的方向过去;如果空间不足,float box就会下移到该line box的下方,如同下图。

例二 inline box在float box之后

<html>
  <head>
  <style type="text/css">	
	.parent{
		width:500px;
		height:120px;
		margin:20px auto 0;
		padding:10px;
		line-height:30px;
		font-family:"Times New Roman",Georgia,Serif;
		border:solid 2px rgba(247, 79, 79, 0.56);
	}
	.float-child{
		width:100px;
		height:50px;
		float:left;
		margin-right:10px;
		box-sizing:border-box;
		background:rgba(247, 79, 79, 0.56);
	}	
  </style>
  </head>
<body>
  <div class='parent'>
    <div class='float-child'>
</div>
    <span>I'm inline element. I'm inline element. I'm inline element. I'm inline element. I'm inline element. I'm inline element. I'm inline element. I'm inline element. I'm inline element. </span>
  </div>
</body>
</html>
复制代码

浏览器上显示为:

因为float box在inline box的前面,所以它会先占据一块空间。在左边有float box占据的情况下,line box的宽度为 containing block的宽度 — float box的宽度;一旦float box没有占据横向空间了,line box的宽度即为containing block的宽度。而inline box中的文字会依次排在这些line box中,一个line box排不满,换行到下一个line box中。

对应的box图如下:

非inline box的inline-level box

该box的行为与inline box类似,只不过它是以一个整体的形式参与到inline formatting context中。这就意味着,它能否围绕float box取决于containing block的宽度是否足够放置float box和它本身。

例三 containing block的宽度足够

<html>
  <head>
  <style type="text/css">	
	.parent{
		width:500px;
		height:120px;
		margin:20px auto 0;
		padding:10px;
		line-height:30px;
		font-family:"Times New Roman",Georgia,Serif;
		border:solid 2px rgba(247, 79, 79, 0.56);
	}
	.float-child{
		width:100px;
		height:50px;
		float:left;
		margin-right:10px;
		box-sizing:border-box;
		background:rgba(247, 79, 79, 0.56);
	}	
	.normal-child{
		width:350px;
		display:inline-block;
		border:solid 1px rgba(247, 79, 79, 0.56);
		margin-bottom:5px;
		padding-left:5px;
	}
  </style>
  </head>
<body>
  <div class='parent'>
    <span class='normal-child'>I'm first inline-level box, but not a inline box. </span>
    <span class='normal-child'>I'm second inline-level box, but not a inline box. </span>
    <span class='normal-child'>I'm third inline-level box, but not a inline box. </span>
    <div class='float-child'></div>
  </div>
</body>
</html>
复制代码

浏览器上显示如下:

上图中,三个span元素会产生三个非inline box的inline-level box,第二个box不足以放到第一个box之后,于是,它下移到第一个box下方,同理第三个box。接着,因为float box是排在第三个box后面,且第三行横向空余空间足够放置float box,故float box会与第三个box同行,并向左浮动。

如果此时做点改动,在浮动元素后面再放置两个同样的span,会是什么情况呢?

修改部分css代码:

	.parent{
		width:500px;
		height:180px;
		margin:20px auto 0;
		padding:10px;
		line-height:30px;
		font-family:"Times New Roman",Georgia,Serif;
		border:solid 2px rgba(247, 79, 79, 0.56);
	}复制代码

修改body内容如下:

<body>
  <div class='parent'>
    <span class='normal-child'>I'm first inline-level box, but not a inline box. </span>
    <span class='normal-child'>I'm second inline-level box, but not a inline box. </span>
    <span class='normal-child'>I'm third inline-level box, but not a inline box. </span>
    <div class='float-child'></div>
    <span class='normal-child'>I'm forth inline-level box, but not a inline box. </span>
    <span class='normal-child'>I'm fifth inline-level box, but not a inline box. </span>
  </div>
</body>
复制代码

效果如下:

修改之后,文字完美的包围了float box。对于第四个inline-level box,如果float box不存在,它会紧挨着第三个inline-level box上下排列。 但现在前方横空杀出了一个float box,还慷慨的给了它足够地盘,故它会与float box并行排列。对于第五个inline-level box,它眼前是无任何阻挡,故会沿着containing block的左边缘排列。

例四 containing block的宽度不足

在containing block宽度不足的情况下,float box与非inline box的inline-level box是不能并行排列的,它们只存在上下的关系。

<html>
  <head>
  <style type="text/css">	
	.parent{
		width:500px;
		height:130px;
		margin:20px auto 0;
		padding:10px;
		line-height:30px;
		font-family:"Times New Roman",Georgia,Serif;
		border:solid 2px rgba(247, 79, 79, 0.56);
	}
	.float-child{
		width:120px;
		height:50px;
		float:left;
		margin-right:10px;
		box-sizing:border-box;
		background:rgba(247, 79, 79, 0.56);
	}	
	.normal-child{
		width:400px;
		display:inline-block;
		border:solid 1px rgba(247, 79, 79, 0.56);
		margin-top:5px;
		margin-bottom:5px;
		padding-left:5px;
	}
  </style>
  </head>
<body>
  <div class='parent'>
    <span class='normal-child'>I'm inline-level box in front of float, but not a inline box. </span>
    <div class='float-child'></div>
    <span class='normal-child'>I'm inline-level box after float, but not a inline box. </span>
  </div>
</body>
</html>
复制代码

效果如下:

上例中,第一个span产生的box渲染之后,只剩下500-400 = 120px的空间,不足以放置float box,float box下移,占据120px的空间,待第二个span产生的box渲染时,由于只剩下500-120 = 380px的空间,不足以放置而下移到float box之下。

对比inline box及非inline box的inline-level box,我们发现,它们其实很相似,唯一的不同点在于参与inline formatting context的形式不同,一个是里面的单个文字参与,一个是整体参与,除非containing block的宽度不足,否则页面的效果是一样的。

还有个block-level box,又是个复杂的料,先写到这吧,下篇接着讲!

ps: 本文例子均是在chrome 49.0上测试。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值