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布局。
人人网热门分享inline-block布局 张鑫旭-鑫空间-鑫生活

其通过也是通过增大父标签的宽度来实现看上去的“两端对齐”效果的,不过其不是通过width属性来增加父标签的宽度的,而是使用的margin负值(我个人推荐使用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实现列表元素的两端对齐。

说穿了其实很简单,我们不妨以最常见的列表标签-ulli标签举例,要实现li列表的两端对齐,直接下面这点CSS代码就OK了:

ul{text-align:justify;}
li{display:inline-block;}

简单得让人当场吐血三升。

唯一需要注意的就是列表元素首尾标签留空(或换行),如下图所示:
标签首尾换行 张鑫旭-鑫空间-鑫生活首尾标签留空 张鑫旭-鑫空间-鑫生活

不能够上一个标签组的结束标签与下一个标签组的其实标签连在一起,如下图所示:
标签不能连在一起 张鑫旭-鑫空间-鑫生活

不仅如此,对于IE8浏览器,列表元素不能处在font-size:0的环境下至少code>font-size:1px,因为IE8浏览器font-size:0或直接把换行空格或普通空格抹掉而无法实现两端对齐效果。

ok,下面是重头戏了,纠缠不清的IE6/IE7浏览器。显然上面的ulli样式组合在IE6/7浏览器下是行不通的,即使你使用hack

让IE6/7下的li标签有类似于display:inline-block的特性也是没有作用的。那么如何才能让IE6/7浏览器也有列表元素支持

text-align:justify属性呢?经过我反复试验与调试,总结了两点:inline标签化以及结束标签连续化

1. inline标签化
所谓“inline标签化”就是列表元素需要使用inline水平的标签,例如spanastrongem等,像lidiv这些标签就不可以。

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浏览器也就能够实现列表元素的两端对齐啦!

为了便于更直观的知道各个浏览器下实现两端对齐效果需要注意的事项,我特地制作了下表:

各个浏览器实现text-align:justify下的两端对齐布局注意事项表
浏览器 注意事项
IE6 inline水平列表标签、列表结束标签连续、列表元素间换行或留空
IE7 inline水平列表标签、列表结束标签连续、列表元素间换行或留空
IE8 列表元素间换行或留空、列表元素的环境字体大小不能为0
现代浏览器 列表元素间换行或留空

 

然而,现在还有一个很悲剧的问题没有解决,就是当列表元素最后一行无法两端对齐的悲剧。如下图所示:

text-justify下的悲剧最后一行 张鑫旭-鑫空间-鑫生活

其实这个问题很好解决的。

如何悲剧变喜剧?
列表(或文字)要两端对齐的前提就是内容必须超过一行,所以,要解决最后一行元素无法两端对齐的文字其实很简单,就是在列表(或文字段)的最后创建一个高度为0的宽度100%的透明的inline-block的标签层就可以了,例如:

.justify_fix{display:inline-block; width:100%; height:0; overflow:hidden;}

如下HTML:

<span class="justify_fix"></span>

例如拿先前最后一行列表悲剧的demo举例,现在在该demo列表最后添加上面类名为justify_fixspan元素,结果最后一行两端对齐排列了,如下图变化:
末行元素也两端对齐了 张鑫旭-鑫空间-鑫生活


补充 on 2011-03-16:
很多时候,我们希望列表的最后一行是左对齐排列的,而不是两端对齐,这时候怎么办呢?原理与上面的两端对齐一致。就是复制几个列表元素的外层标签,等宽,但高度为0,里面就是个&nbsp;(不可缺),复制的个数一般就是每行元素的列表个数啦,这样肯定可以保证最后一行元素一定是左对齐排列的啦!

如下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">&nbsp;</span>
    <span class="list left_fix">&nbsp;</span>
    <span class="list left_fix">&nbsp;</span>
    <span class="list left_fix">&nbsp;</span>
    <span class="list left_fix">&nbsp;</span>
</div>

上面HTML中的left_fix样式如下:

.left_fix{height: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浏览器):
人人网热门列表justify下两端对齐效果截图 张鑫旭-鑫空间-鑫生活

CSS代码如下:

.video-list{width:540px; margin-left:auto; margin-right:auto; text-align:justify;} /*列表父容器*/
.text-justify-list{display:inline-block; width:97px; margin-bottom:15px; text-align:left; vertical-align:top;}/*列表元素*/

.
. /* 完全人人网CSS代码*/
.

.justify_fix{display:inline-block; width:100%; height:0; overflow:hidden;}/*末行悲剧变喜剧*/

可以看到列表元素压根就没有设置垂直方向上的margin或是padding值,就单单一个宽度值,但是列表元素确实两端对齐,等间距排列。没有计算,没有有意去增加父容器宽度等,超简单就实现了。

比对上面提到的些注意事项,看看这个例子中的HTML代码是如何实践上面的注意事项的:
①inline水平标签
如下截图所示:
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>

效果如图:




参考:http://www.zhangxinxu.com/wordpress/2011/03/displayinline-blocktext-alignjustify%E4%B8%8B%E5%88%97%E8%A1%A8%E7%9A%84%E4%B8%A4%E7%AB%AF%E5%AF%B9%E9%BD%90%E5%B8%83%E5%B1%80/


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值