display:inline-block/text-align:justify下列表的两端对齐布局
Posted 小向光
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了display:inline-block/text-align:justify下列表的两端对齐布局相关的知识,希望对你有一定的参考价值。
一、如何实现元素的两端对齐
CSS2中text-align
有一个属性值为justify
,为对齐之意。其实现的效果就是可以让一行文字两端对齐显示(文字内容要超过一行),text-align不会处理被打断的行和最后一行。
text-align
其诞生的意义是控制文字的对齐与显示的,从其属性名上就可以看出来。从其渲染与解析上来看,其主要是用来控制
inline水平元素或inline-block元素的对齐与显示的,例如嵌套行内标签的文字、图片、input表单控件等;
而对block水平的元素是没有作用的。
所以,对于列表元素,理论上,我们只要将原本block水平的列表元素inline化或是inline-block化就可以轻松实现其两端对齐了。然而考虑到实际情况,inline水平化显然是不可能的,因为不能给列表元素定宽定高,设置垂直方向上的间距等,列表元素就像是一摊烂泥,根本没法用来砌房子;而inline-block化也是有重重阻碍的,因为IE6/7并不真正意义上的支持inline-block属性。
二、目前列表元素如何实现两端对齐的
方法多多。
① 首先看淘宝网首页热卖单品的例子,如下截图:
其列表布局使用的是传统的浮动(float)布局,通过width
属性强行增大父容器的宽度来实现看上去的“两端对齐”效果的。
② 再看人人网热门分享的两端对齐效果的实现方法,我在之前“基于display:inline-block的列表布局”一文中已经提过,人人网这里的列表布局为inline-block布局。
其通过也是通过增大父标签的宽度来实现看上去的“两端对齐”效果的,不过其不是通过width
属性来增加父标签的宽度的,而是使用的margin负值(我个人推荐使用margin负值而不是定宽):
③ 还有一种方法就是利用white-space: nowrap
,此方法需在inline-block布局基础上使用,一般用在实现单行列表元素看上去的“两端对齐”效果上。white-space: nowrap
会强制列表元素不换行,于是你无需设定父标签容器的宽度或是通过margin
负值等手段增加父容器的宽度等。这里不展开,以后有机会要好好说一说white-space: nowrap
这个很有用的CSS声明的。
以上就是目前几种常见的实现列表元素看上去的“两端对齐”效果方法。怎么样,是不是每个都很折腾——首先列表元素排列就已经很折腾人的了(定宽,计算间距),然后还有人为增加父容器的宽度,同时祖辈元素还要溢出隐藏(overflow:hidden
),oh,my lady嘎嘎。我想这就是为什么网上会有前端工程师咆哮体咆哮加班的原因了。
三、text-align:justify实现两端对齐的好处
好处就是简单方便。只要一个简单的text-align:justify
声明,里面的元素就自动等间距两端对齐布局啦!根本无需计算每个列表元素间的margin间距,更不用去修改父容器的宽度。
四、display:inline-block/text-align:justify下列表的两端对齐布局
为了表述上逻辑清晰。我们先把IE6和IE7浏览器晾在一边,看看IE8+浏览器以及现代浏览器下如何display:inline-block
+text-align:justify
实现列表元素的两端对齐。
说穿了其实很简单,我们不妨以最常见的列表标签-ul
, li
标签举例,要实现li
列表的两端对齐,直接下面这点CSS代码就OK了:
ultext-align:justify;
lidisplay:inline-block;
简单得让人当场吐血三升。
唯一需要注意的就是列表元素首尾标签留空(或换行),如下图所示:
不能够上一个标签组的结束标签与下一个标签组的其实标签连在一起,如下图所示:
不仅如此,对于IE8浏览器,列表元素不能处在font-size:0
的环境下,至少code>font-size:1px,因为IE8浏览器font-size:0
或直接把换行空格或普通空格抹掉而无法实现两端对齐效果。
ok,下面是重头戏了,纠缠不清的IE6/IE7浏览器。显然上面的ul
, li
样式组合在IE6/7浏览器下是行不通的,即使你使用hack
让IE6/7下的li
标签有类似于display:inline-block
的特性也是没有作用的。那么如何才能让IE6/7浏览器也有列表元素支持
text-align:justify
属性呢?经过我反复试验与调试,总结了两点:inline标签化以及结束标签连续化。
1. inline标签化
所谓“inline标签化”就是列表元素需要使用inline水平的标签,例如span
, a
, strong
, em
等,像li
, div
这些标签就不可以。
2. 结束标签连续化
所谓“结束标签连续化”是指列表元素及其内部标签的结束标签需要连在一起。例如下面这个就是不行的:
<span>
<a href="#">
<img src="test.jpg" />
</a>
<span>描述</span>
</span>
而应该是这个样子滴:
<span>
<a href="#">
<img src="test.jpg" />
</a>
<span>描述</span></span>
我们已经习惯了结构化的缩进,所以上面结束标签连写看上去很不自然,有些别扭。但是,为了实现效果,这是没有办法的事情。注意:如果列表标签内嵌多层,则所有层级的结束标签都要连续。
IE6/IE7浏览器同时满足上面的inline标签化以及结束标签连续化,再加上先前现代浏览器下的首尾标签留空,IE6/IE7浏览器也就能够实现列表元素的两端对齐啦!
为了便于更直观的知道各个浏览器下实现两端对齐效果需要注意的事项,我特地制作了下表:
浏览器 | 注意事项 |
---|---|
IE6 | inline水平列表标签、列表结束标签连续、列表元素间换行或留空 |
IE7 | inline水平列表标签、列表结束标签连续、列表元素间换行或留空 |
IE8 | 列表元素间换行或留空、列表元素的环境字体大小不能为0 |
现代浏览器 | 列表元素间换行或留空 |
然而,现在还有一个很悲剧的问题没有解决,就是当列表元素最后一行无法两端对齐的悲剧。如下图所示:
其实这个问题很好解决的。
如何悲剧变喜剧?
列表(或文字)要两端对齐的前提就是内容必须超过一行,所以,要解决最后一行元素无法两端对齐的文字其实很简单,就是在列表(或文字段)的最后创建一个高度为0的宽度100%的透明的inline-block的标签层就可以了,例如:
.justify_fixdisplay:inline-block; width:100%; height:0; overflow:hidden;
如下html:
<span class="justify_fix"></span>
例如拿先前最后一行列表悲剧的demo举例,现在在该demo列表最后添加上面类名为justify_fix
的span
元素,结果最后一行两端对齐排列了,如下图变化:
补充 on 2011-03-16:
很多时候,我们希望列表的最后一行是左对齐排列的,而不是两端对齐,这时候怎么办呢?原理与上面的两端对齐一致。就是复制几个列表元素的外层标签,等宽,但高度为0,里面就是个
(不可缺),复制的个数一般就是每行元素的列表个数啦,这样肯定可以保证最后一行元素一定是左对齐排列的啦!
如下HTML代码:
<div class="box"> <span class="list"><img data-src="http://image.zhangxinxu.com/image/study/s/s128/mm9.jpg" /> 哇哦,美女,口水,鼻血~~~</span> <span class="list"><img data-src="http://image.zhangxinxu.com/image/study/s/s128/mm9.jpg" /> 哇哦,美女,口水,鼻血,不行了,我的小兔乱撞~~</span> . . . <span class="list left_fix"> </span> <span class="list left_fix"> </span> <span class="list left_fix"> </span> <span class="list left_fix"> </span> <span class="list left_fix"> </span> </div>
上面HTML中的left_fix
样式如下:
.left_fixheight:0; padding:0; overflow:hidden;
结果先前等宽对齐的最后三个图片就与上面元素垂直对齐且左对齐啦!(下图截自IE7浏览器)
您可以狠狠地点击这里:最后一行元素左对齐排列demo
于是,综合上面所有讨论,我们就可以相对比较完美地实现列表元素在text-align:justify的两端对齐效果了。
补充于 2015-12-24
今天查看评论,发现好多小伙伴提到占位的元素会导致莫名的空白高度。关于这个问题,可参考“CSS深入理解vertical-align和line-height的基友关系”的“④ 复杂现象”部分。有分析原因以及提供解决方案。
七、text-align:justify下两端对齐效果实例
我们拿上面人人网热门分享处的inline-block列表布局举例。
您可以狠狠地点击这里:人人网热门分享列表text-justify下两端对齐demo
效果如下图(截自IE7浏览器):
CSS代码如下:
.video-listwidth:540px; margin-left:auto; margin-right:auto; text-align:justify; /*列表父容器*/ .text-justify-listdisplay:inline-block; width:97px; margin-bottom:15px; text-align:left; vertical-align:top;/*列表元素*/ . . /* 完全人人网CSS代码*/ . .justify_fixdisplay:inline-block; width:100%; height:0; overflow:hidden;/*末行悲剧变喜剧*/
可以看到列表元素压根就没有设置垂直方向上的margin
或是padding
值,就单单一个宽度值,但是列表元素确实两端对齐,等间距排列。没有计算,没有有意去增加父容器宽度等,超简单就实现了。
比对上面提到的些注意事项,看看这个例子中的HTML代码是如何实践上面的注意事项的:
①inline水平标签
如下截图所示:
②列表结束标签连续
如下图所示:
③列表标签换行或留空
如下截图所示:
如此,你也可以轻轻松松实现列表元素的两端对齐布局,而且不用去担心兼容性问题!!GO!大胆的去使用吧!
补充:
“text-align CSS属性定义行内内容(例如文字)如何相对它的块父元素对齐。text-align并不控制块元素自己的对齐,只控制它的行内内容的对齐。”从这里可以看出,控制文本居中对齐直接写text-align:justify就可以。但是这对于多行文本(即有文本换行)除了最后一行都可以实现两端对齐,最后一行依旧左对齐。所以就需要控制最后一行文本对齐方式的CSS属性:text-align-last。
2.text-align-last
text-align-last 属性规定如何对齐文本的最后一行。但是这里注意一点text-align-last 属性只有在 text-align 属性设置为 “justify” 时才起作用。所以,利用这个属性就可以控制最后一行文本的对齐方式。我们可以想象,如果是单行文本,就可以当作最后一行文本处理,直接设置text-align-last:justify来实现当行文本两端对齐,可惜的是,这样的方法兼容性并不好。
为了兼容IE6/7,使用text-align:justify时需要结合另外一个IE私有属性:text-justify:inter-ideograph ;
text-justify语法:
text-justify : auto |inter-word | newspaper | distribute | distribute-all-lines | inter-ideograph
text-justify参数
auto:允许浏览器用户代理确定使用的两端对齐法则 ;
inter-word:通过增加字之间的空格对齐文本。该行为是对齐所有文本行最快的方法。它的两端对齐行为对段落的最后一行无效 ;
newspaper :通过增加或减少字或字母之间的空格对齐文本。是用于拉丁文字母表两端对齐的最精确格式 ;
distribute:处理空格很像newspaper,适用于东亚文档。尤其是泰国 ;
distribute-all-lines:两端对齐行的方式与distribute相同,也同样不包含两段对齐段落的最后一行。适用于表意字文档 ;
inter-ideograph:为表意字文本提供完全两端对齐。他增加或减少表意字和词间的空格。
因此我们要把text-align:justify;text-justify:inter-ideograph;放在一起来兼容IE浏览器:
再添加一个完整的例子:
<!DOCTYPE HTML>
<html>
<head>
<title>文本两端对齐 by hongchenok</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
.box
width:50%;
padding:20px;
margin:20px auto;
background-color:#f0f3f9;
text-align:justify;
text-justify:inter-ideograph;/*ie6-8*/
.list
width:120px;
display:inline-block;
*display: inline;
*zoom:1;
padding-bottom:20px;
text-align:center;
vertical-align:top;
.justify_fix
display:inline-block;
*display: inline;
*zoom:1; width:100%;
height:0;
overflow:hidden;
.list_head
height: 50px;
width: 50px;
background-color: red;
float: left;
.list_content
width: 70px;
height: 50px;
float: left;
.clearfix:after
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
* html .clearfix height: 1%;
</style>
</head>
<body>
<div class="box">
<div class="list clearfix">
<div class="list_head"></div>
<div class="list_content">这是内容</div>
</div>
<div class="list clearfix">
<div class="list_head"></div>
<div class="list_content">这是内容</div>
</div>
<span class="justify_fix"></span>
</div>
<div class="box">
<div class="list clearfix">
<div class="list_head"></div>
<div class="list_content">这是内容</div>
</div>
<div class="list clearfix">
<div class="list_head"></div>
<div class="list_content">这是内容</div>
</div>
<div class="list clearfix">
<div class="list_head"></div>
<div class="list_content">这是内容</div>
</div>
<div class="list clearfix">
<div class="list_head"></div>
<div class="list_content">这是内容</div>
</div>
<span class="justify_fix"></span>
</div>
</body>
</html>
效果如图:
以上是关于display:inline-block/text-align:justify下列表的两端对齐布局的主要内容,如果未能解决你的问题,请参考以下文章