我如何*真的*certificateHTML + CSS的水平菜单?

你可以在HTML中的菜单栏上find很多教程,但是对于这个特定的(尽pipe恕我直言)通用案例,我还没有find任何像样的解决scheme:

# THE MENU ITEMS SHOULD BE JUSTIFIED JUST AS PLAIN TEXT WOULD BE # # ^ ^ # 
  • 有不同数量的文本菜单项,页面布局是stream畅的。
  • 第一个菜单项应该是左alignment的,最后一个菜单项应该是右alignment的。
  • 其余的项目应该在菜单栏上最佳地分配。
  • 数量是变化的,所以没有机会预先计算最佳宽度。

请注意,TABLE在这里也不起作用:

  • 如果你把所有的TD中间,第一个和最后一个项目没有正确alignment。
  • 如果左alignment并右alignment第一个对象。 最后的项目,间距将是次优的。

使用HTML和CSS以干净的方式没有明显的方法来实现这一点不奇怪吗?

现代方法 – Flexboxes !

现在, CSS3柔印盒有更好的浏览器支持 ,我们有些人终于可以开始使用它们了。 只需添加更多的供应商前缀以获得更多浏览器覆盖

在这种情况下,您只需将父元素的displayflex ,然后将justify-content属性更改为space-betweenspace-around ,以便在子柔性框项目之间或周围添加空格。

使用justify-content: space-between – ( 这里的例子)

 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> 

要做的最简单的事情就是通过在行的末尾插入一个元素来强制该行中断,这个元素将占用超过剩余空间的空间,然后隐藏它。 我用一个简单的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> 

好的,这个解决scheme在IE6 / 7上不起作用,因为:before / :after缺less支持:

 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> 

有一个解决scheme。 适用于FF,IE6,IE7,Webkit等

确保在closuresspan.inner之前不要放置任何空格。 IE6将打破。

你可以select给.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> 

适用于Opera,Firefox,Chrome和IE

 ul { display: table; margin: 1em auto 0; padding: 0; text-align: center; width: 90%; } li { display: table-cell; border: 1px solid black; padding: 0 5px; } 

又一个解决scheme。 我没有select解决像添加尊敬的类等的HTML,所以我find了一个纯粹的CSS方式。

适用于Chrome,Firefox,Safari …不知道IE。

testing: 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> 

让它成为一个<p>text-align: justify

更新 :没关系。 这根本不像我想的那样工作。

更新2 :现在在IE以外的浏览器中都不起作用,但是CSS3以text-align-last的forms支持

对于基于Gecko的浏览器,我想出了这个解决scheme。 尽pipe(例如Chromium,Midori,Epiphany),这个解决scheme并不适用于WebKit浏览器,但它们仍然显示最后一个项目之后的尾部空格。

我把菜单栏放在合理的段落里 。 问题是,有理由的段落的最后一行不会被certificate是合理的,原因很明显。 因此,我添加了一个很宽的隐形元素(例如img),以保证该段至less有两行。

现在菜单栏通过浏览器用于validation纯文本的相同algorithm是合理的。

码:

 <div style="width:500px; background:#eee;"> <p style="text-align:justify"> <a href="#">THE&nbsp;MENU&nbsp;ITEMS</a> <a href="#">SHOULD&nbsp;BE</a> <a href="#">JUSTIFIED</a> <a href="#">JUST&nbsp;AS</a> <a href="#">PLAIN&nbsp;TEXT</a> <a href="#">WOULD&nbsp;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> 

备注:你注意到我被骗了吗? 要添加空间填充元素,我必须猜测一下菜单栏的宽度。 所以这个解决scheme并不完全符合规则。

如果句子自然会导致换行符,那么文本是合理的。 所以你所要做的就是自然而然地强制换行,并且在第二行隐藏什么:

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 eg 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">&nbsp;</li> </ul> 

li.break元素必须与最后一个菜单项位于同一行,并且必须包含一些内容(在本例中为非打破空格),否则在某些浏览器中,如果不在同一行上,则会看到一些在行尾有额外的空间,如果它不包含任何内容,则会被忽略,行不合理。

testing了IE7,IE8,IE9,Chrome,Firefox 4。

如果去与可能的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("..http://img.dovov.combg-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("..http://img.dovov.combg-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> 

更简单的标记,在Opera,FF,Chrome,IE7,IE8testing:

 <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; } 

现场示例 。

这可以通过一些仔细的测量和最后一个孩子select器完美实现。

 ul li { margin-right:20px; } ul li:last-child { margin-right:0; } 

我知道原来的问题指定了HTML + CSS,但是并没有专门说没有javascript ;)

尽量保持css和标记尽可能干净,尽可能在语义上有意义(使用UL作为菜单),我提出了这个build议。 可能不理想,但可能是一个很好的起点:

 <!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>