如何真正证明HTML + CSS中的水平菜单?

时间:2020-03-05 18:49:18  来源:igfitidea点击:

我们可以在HTML的菜单栏上找到很多教程,但是对于这种特定的(尽管是恕我直言)通用案例,我还没有找到任何合适的解决方案:

#  THE MENU ITEMS    SHOULD BE    JUSTIFIED     JUST AS    PLAIN TEXT     WOULD BE  #
#  ^                                                                             ^  #
  • 纯文本菜单项的数量不尽相同,页面布局也很流畅。
  • 第一个菜单项应左对齐,最后一个菜单项应右对齐。
  • 其余项目应在菜单栏上进行最佳分配。
  • 数字是变化的,因此没有机会预先计算出最佳宽度。

请注意,TABLE在这里也无法正常工作:

  • 如果将所有TD居中,则第一项和最后一项不会正确对齐。
  • 如果左对齐,右对齐第一个。最后一项,间隔将不是最佳的。

难道没有明显的方法可以通过使用HTML和CSS以干净的方式实现此功能吗?

解决方案

回答

text-align:justify使其成为<p>吗?

更新:没关系。就像我想的那样,那根本不起作用。

更新2:目前无法在IE以外的任何浏览器中使用,但是CSS3以text-align-last的形式支持此功能

回答

对于基于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>

备注:你注意到我被骗了吗?要添加空格元素,我必须对菜单栏的宽度进行一些猜测。因此,这种解决方案并不完全符合规则。

回答

我知道最初的问题指定了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>

回答

最简单的方法是通过在行的末尾插入一个元素(该元素将占用比剩余的可用空间更多的内容),然后隐藏它来迫使行断开。我可以通过一个简单的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的宽度,但是希望我们能理解并适应它。

回答

有一个解决方案。适用于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>

回答

是否使用可能的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>