你在HTML中的菜单栏上找到了很多教程,但是对于这个特定的(虽然是IMHO泛型),我还没有找到任何合适的解决方案:
# THE MENU ITEMS SHOULD BE JUSTIFIED JUST AS PLAIN TEXT WOULD BE #
# ^ ^ #
请注意,这里的TABLE也不起作用:
使用HTML和CSS以干净的方式实现这一点并不是很奇怪吗?
答案 0 :(得分:83)
最简单的方法是通过在行的末尾插入一个元素来强制行断开,该元素将占用多于左边的可用空间然后隐藏它。我很容易用一个简单的span
元素完成这个:
#menu {
text-align: justify;
}
#menu * {
display: inline;
}
#menu li {
display: inline-block;
}
#menu span {
display: inline-block;
position: relative;
width: 100%;
height: 0;
}
<div id="menu">
<ul>
<li><a href="#">Menu item 1</a></li>
<li><a href="#">Menu item 3</a></li>
<li><a href="#">Menu item 2</a></li>
</ul>
<span></span>
</div>
#menu span
选择器中的所有垃圾都是(据我所知)大多数浏览器都需要的。它应该强制span
元素的宽度为100%,这应该会导致换行,因为它由于display: inline-block
规则而被视为内联元素。 inline-block
也使span
成为块级样式规则,如width
,这会导致元素与菜单不一致,从而使菜单换行。
您当然需要将span
的宽度调整为您的用例和设计,但我希望您能获得一般性的想法,并且可以对其进行调整。
答案 1 :(得分:42)
既然CSS3 flexboxes有better browser support,我们中的一些人终于可以开始使用它们了。只需为more browser coverage添加其他供应商前缀。
在这种情况下,您只需将父元素的display
设置为flex
,然后将justify-content
property更改为space-between
或space-around
,以便在子Flexbox项目之间或周围添加空格。
使用justify-content: space-between
- (example here):
ul {
list-style: none;
padding: 0;
margin: 0;
}
.menu {
display: flex;
justify-content: space-between;
}
<ul class="menu">
<li>Item One</li>
<li>Item Two</li>
<li>Item Three Longer</li>
<li>Item Four</li>
</ul>
使用justify-content: space-around
- (example here):
ul {
list-style: none;
padding: 0;
margin: 0;
}
.menu {
display: flex;
justify-content: space-around;
}
<ul class="menu">
<li>Item One</li>
<li>Item Two</li>
<li>Item Three Longer</li>
<li>Item Four</li>
</ul>
答案 2 :(得分:12)
好的,这个解决方案不适用于IE6 / 7,因为:before
/ :after
缺乏支持,但是:
ul {
text-align: justify;
list-style: none;
list-style-image: none;
margin: 0;
padding: 0;
}
ul:after {
content: "";
margin-left: 100%;
}
li {
display: inline;
}
a {
display: inline-block;
}
<div id="menu">
<ul>
<li><a href="#">Menu item 1</a></li>
<li><a href="#">Menu item 2</a></li>
<li><a href="#">Menu item 3</a></li>
<li><a href="#">Menu item 4</a></li>
<li><a href="#">Menu item 5</a></li>
</ul>
</div>
我将a标签作为inline-block
的原因是因为我不希望内部的单词也被证明是合理的,我也不想使用非中断空格。
答案 3 :(得分:8)
有一个解决方案。适用于FF,IE6,IE7,Webkit等。
确保在关闭span.inner
之前不要添加任何空格。 IE6将会破解。
您可以选择.outer
宽度
.outer {
text-align: justify;
}
.outer span.finish {
display: inline-block;
width: 100%;
}
.outer span.inner {
display: inline-block;
white-space: nowrap;
}
<div class="outer">
<span class="inner">THE MENU ITEMS</span>
<span class="inner">SHOULD BE</span>
<span class="inner">JUSTIFIED</span>
<span class="inner">JUST AS</span>
<span class="inner">PLAIN TEXT</span>
<span class="inner">WOULD BE</span>
<span class="finish"></span>
</div>
答案 4 :(得分:3)
又一个解决方案。我没有办法解决html问题,比如添加杰出的类等等,所以我发现了一种纯粹的CSS方式。
适用于Chrome,Firefox,Safari ..不了解IE。
测试:http://jsfiddle.net/c2crP/1
ul {
margin: 0;
padding: 0;
list-style: none;
width: 200px;
text-align: justify;
list-style-type: none;
}
ul > li {
display: inline;
text-align: justify;
}
/* declaration below will add a whitespace after every li. This is for one line codes where no whitespace (of breaks) are present and the browser wouldn't know where to make a break. */
ul > li:after {
content: ' ';
display: inline;
}
/* notice the 'inline-block'! Otherwise won't work for webkit which puts after pseudo el inside of it's parent instead of after thus shifting also the parent on next line! */
ul > li:last-child:after {
display: inline-block;
margin-left: 100%;
content: ' ';
}
<ul>
<li><a href="#">home</a></li>
<li><a href="#">exposities</a></li>
<li><a href="#">werk</a></li>
<li><a href="#">statement</a></li>
<li><a href="#">contact</a></li>
</ul>
答案 5 :(得分:2)
使用<p>
将其设为text-align: justify
?
更新:没关系。根据我的想法,这根本不起作用。
更新2 :目前在IE以外的任何浏览器中都不起作用,但CSS3以text-align-last
答案 6 :(得分:1)
对于基于Gecko的浏览器,我提出了这个解决方案。但是,此解决方案不适用于WebKit浏览器(例如Chromium,Midori,Epiphany),它们仍会在最后一项之后显示尾随空格。
我将菜单栏放在对齐的段落中。问题是,由于显而易见的原因,合理段落的最后一行不会被证明是合理的。因此,我添加了一个宽大的不可见元素(例如img),它保证该段落至少有两行。
现在,菜单栏由浏览器用于证明纯文本的算法相同。
<强>代码:强>
<div style="width:500px; background:#eee;">
<p style="text-align:justify">
<a href="#">THE MENU ITEMS</a>
<a href="#">SHOULD BE</a>
<a href="#">JUSTIFIED</a>
<a href="#">JUST AS</a>
<a href="#">PLAIN TEXT</a>
<a href="#">WOULD BE</a>
<img src="/Content/Img/stackoverflow-logo-250.png" width="400" height="0"/>
</p>
<p>There's an varying number of text-only menu items and the page layout is fluid.</p>
<p>The first menu item should be left-aligned, the last menu item should be right-aligned. The remaining items should be spread optimal on the menu bar.</p>
<p>The number is varying,so there's no chance to pre-calculate the optimal widths.</p>
<p>Note that a TABLE won't work here as well:</p>
<ul>
<li>If you center all TDs, the first and the last item aren't aligned correctly.</li>
<li>If you left-align and right-align the first resp. the last items, the spacing will be sub-optimal.</li>
</ul>
</div>
备注:你注意到我被骗了吗?要添加空间填充元素,我必须猜测菜单栏的宽度。所以这个解决方案并不完全符合规则。
答案 7 :(得分:1)
如果句子自然导致换行,则文本只是合理的。所以你需要做的就是自然地强制换行,并在第二行隐藏什么:
CSS:
ul {
text-align: justify;
width: 400px;
margin: 0;
padding: 0;
height: 1.2em;
/* forces the height of the ul to one line */
overflow: hidden;
/* enforces the single line height */
list-style-type: none;
background-color: yellow;
}
ul li {
display: inline;
}
ul li.break {
margin-left: 100%;
/* use e.g. 1000px if your ul has no width */
}
HTML:
<ul>
<li><a href="/">The</a></li>
<li><a href="/">quick</a></li>
<li><a href="/">brown</a></li>
<li><a href="/">fox</a></li>
<li class="break"> </li>
</ul>
li.break元素必须与最后一个菜单项在同一行,并且必须包含一些内容(在这种情况下是非破坏空间),否则在某些浏览器中,如果它不在同一行,那么你将在你的行的末尾看到一些小的额外空间,如果它不包含任何内容,那么它将被忽略,并且该行不合理。
在IE7,IE8,IE9,Chrome,Firefox 4中测试。
答案 8 :(得分:0)
如果要使用可能的javascript(此脚本基于mootools)
<script type="text/javascript">//<![CDATA[
window.addEvent('load', function(){
var mncontainer = $('main-menu');
var mncw = mncontainer.getSize().size.x;
var mnul = mncontainer.getFirst();//UL
var mnuw = mnul.getSize().size.x;
var wdif = mncw - mnuw;
var list = mnul.getChildren(); //get all list items
//get the remained width (which can be positive or negative)
//and devided by number of list item and also take out the precision
var liwd = Math.floor(wdif/list.length);
var selw, mwd=mncw, tliw=0;
list.each(function(el){
var elw = el.getSize().size.x;
if(elw < mwd){ mwd = elw; selw = el;}
el.setStyle('width', elw+liwd);
tliw += el.getSize().size.x;
});
var rwidth = mncw-tliw;//get the remain width and set it to item which has smallest width
if(rwidth>0){
elw = selw.getSize().size.x;
selw.setStyle('width', elw+rwidth);
}
});
//]]>
</script>
和css
<style type="text/css">
#main-menu{
padding-top:41px;
width:100%;
overflow:hidden;
position:relative;
}
ul.menu_tab{
padding-top:1px;
height:38px;
clear:left;
float:left;
list-style:none;
margin:0;
padding:0;
position:relative;
left:50%;
text-align:center;
}
ul.menu_tab li{
display:block;
float:left;
list-style:none;
margin:0;
padding:0;
position:relative;
right:50%;
}
ul.menu_tab li.item7{
margin-right:0;
}
ul.menu_tab li a, ul.menu_tab li a:visited{
display:block;
color:#006A71;
font-weight:700;
text-decoration:none;
padding:0 0 0 10px;
}
ul.menu_tab li a span{
display:block;
padding:12px 10px 8px 0;
}
ul.menu_tab li.active a, ul.menu_tab li a:hover{
background:url("../images/bg-menutab.gif") repeat-x left top;
color:#999999;
}
ul.menu_tab li.active a span,ul.menu_tab li.active a.visited span, ul.menu_tab li a:hover span{
background:url("../images/bg-menutab.gif") repeat-x right top;
color:#999999;
}
</style>
和最后一个HTML
<div id="main-menu">
<ul class="menu_tab">
<li class="item1"><a href="#"><span>Home</span></a></li>
<li class="item2"><a href="#"><span>The Project</span></a></li>
<li class="item3"><a href="#"><span>About Grants</span></a></li>
<li class="item4"><a href="#"><span>Partners</span></a></li>
<li class="item5"><a href="#"><span>Resources</span></a></li>
<li class="item6"><a href="#"><span>News</span></a></li>
<li class="item7"><a href="#"><span>Contact</span></a></li>
</ul>
</div>
答案 9 :(得分:0)
更简单的标记,在Opera,FF,Chrome,IE7,IE8中测试:
<div class="nav">
<a href="#" class="nav_item">nav item1</a>
<a href="#" class="nav_item">nav item2</a>
<a href="#" class="nav_item">nav item3</a>
<a href="#" class="nav_item">nav item4</a>
<a href="#" class="nav_item">nav item5</a>
<a href="#" class="nav_item">nav item6</a>
<span class="empty"></span>
</div>
和css:
.nav {
width: 500px;
height: 1em;
line-height: 1em;
text-align: justify;
overflow: hidden;
border: 1px dotted gray;
}
.nav_item {
display: inline-block;
}
.empty {
display: inline-block;
width: 100%;
height: 0;
}
答案 10 :(得分:-1)
这可以通过一些仔细的测量和最后一个孩子选择器完美地实现。
ul li {
margin-right:20px;
}
ul li:last-child {
margin-right:0;
}
答案 11 :(得分:-2)
我知道原始问题指定了HTML + CSS,但它没有具体说没有javascript ;)
尽量保持css和标记尽可能干净,并尽可能在语义上有意义(使用菜单的UL)我提出了这个建议。可能不理想,但它可能是一个很好的起点:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Kind-of-justified horizontal menu</title>
<style type="text/css">
ul {
list-style: none;
margin: 0;
padding: 0;
width: 100%;
}
ul li {
display: block;
float: left;
text-align: center;
}
</style>
<script type="text/javascript">
setMenu = function() {
var items = document.getElementById("nav").getElementsByTagName("li");
var newwidth = 100 / items.length;
for(var i = 0; i < items.length; i++) {
items[i].style.width = newwidth + "%";
}
}
</script>
</head>
<body>
<ul id="nav">
<li><a href="#">first item</a></li>
<li><a href="#">item</a></li>
<li><a href="#">item</a></li>
<li><a href="#">item</a></li>
<li><a href="#">item</a></li>
<li><a href="#">last item</a></li>
</ul>
<script type="text/javascript">
setMenu();
</script>
</body>
</html>