更新 2013 年 4 月:本文相当旧。 这并不难。 只需将列表文本居中(例如
ul.nav { text-align: center; }
)并将列表项设置为内联块(例如 ul.nav li { display: inline-block; }
)。 如果您想出于任何原因使用边距,请查看 width: fit-content;
。编码菜单的当前标准是无序列表。 它不像 <nav>
标签那样语义,但也不错。 毕竟,导航是各种列表。
如果您想使此导航无序列表水平,您基本上有两种选择
- 使列表项内联,而不是默认的块。 .li { display: inline; } 这不会在列表项之后强制换行,它们将尽可能水平排列。
- 浮动列表项。 由于我们经常希望列表项显示为块,以便我们能够为它们设置固定宽度,因此我们被迫将它们浮动到左侧或右侧以水平排列它们。

现在,让我们对如何显示此菜单做出一些常见的决定
- 我们希望菜单居中。 无论菜单是在固定宽度环境还是流体宽度环境中,我们都希望菜单元素在父元素中居中
- 菜单将是一个水平条,因此我们希望确保该条在视觉上看起来像一条条。 我们想为此使用重复的背景图像。
现在我们遇到了麻烦。 <ul>
本身无法负责背景图像,因为它只会在必要时才能帮助居中。 因此,我们将其放在一个宽度为 100% 的 div 内以处理背景图像。 但现在我们的居中技巧不起作用。 说实话,我不确定为什么,但是应用 .ul {margin: 0 auto;} 在这里不起作用。 这就是技巧所在……
将列表包装在表格 div 内
如果我们将菜单包装在一个“表格”div 中,我们就可以解决这个问题。 如果您熟悉来自 CSSPlay 的 Stu Nicholls,他经常在他的很棒的水平菜单上使用此 方法。 查看 HTML
<div id="menu-outer">
<div class="table">
<ul id="horizontal-list">
<li><a href="#"><img src="images/list-item-1.gif" alt="list item 1" /></a></li>
<li><a href="#"><img src="images/list-item-2.gif" alt="list item 2" /></a></li>
<li><a href="#"><img src="images/list-item-3.gif" alt="list item 3" /></a></li>
<li><a href="#"><img src="images/list-item-4.gif" alt="list item 4" /></a></li>
</ul>
</div>
</div>
现在看看使它发生的非常简单的 CSS
#menu-outer {
height: 84px;
background: url(images/bar-bg.jpg) repeat-x;
}
.table {
display: table; /* Allow the centering to work */
margin: 0 auto;
}
ul#horizontal-list {
min-width: 696px;
list-style: none;
padding-top: 20px;
}
ul#horizontal-list li {
display: inline;
}
是表格 div 完成了这项工作。 有些时候我认为“无论什么有效”应该是 CSS 的口号。
它在 IE7 中不起作用。
更改
ul#horizontal-list li {
float: left;
}
到
ul#horizontal-list li {
display:inline
}
它很好。
但是当 li 元素不是 img 时。
它不是最好的。
@Mogly:是的,你说得对。 IE 不喜欢浮动。 奇怪。 我已经更新了文章以反映更改。 也许如果列表项是文本而不是图像,它可能不会那么干净,但我仍然认为它会没问题。 只要你在菜单元素之间应用足够的间距。 至少它们仍然会居中。
一个问题 Chris - 为什么你需要为此使用列表? 为什么不能简单地将图像并排浮动?
我问是因为我在所有地方都看到列表,我只是看不出它们在导航中的必要性。 为什么程序员不能简单地使用“{ display:block; }”?
以我的网站为例:http://davidwalsh.name
如果您查看导航代码,它只是一个包含一堆锚标签的 div - 没有列表。 从 WordPress 中删除不必要的列表真是一件痛苦的事情。 在导航的情况下,列表实际上是带宽的浪费。
嗯……对于我的联系栏,我只是做了
ul.contact { width: 100%; text-align: center; }
和
ul.contact li { display: inline; }
就这样。 我错过了什么吗? 当然,现在如果列表中有太多项,它们将开始换行。
它在 http://robertobaca.com 底部(出于某种原因,我对主导航没有这样做,我想那时没有想到)
@David Walsh:有很多理由使用列表。 首先,将菜单包装在某些东西中,这样你就可以有一些定位可能性。 带有唯一 ID 的 <ul> 似乎经常符合要求。 在您的网站上,您似乎将它包装在一个 DIV 中。 使用列表,您可以获得 <li> 元素和锚元素来设置样式,这为您提供了一些额外的选项。 您可能今天不需要它们,但是为将来您可能想到的重新设计想法而拥有控制权很好。
@Roberto:是的,这开始变得有点令人困惑……假设你想为你的联系栏中的每个列表项声明一个绝对宽度,这是一个合理的要求。 你需要使用块级元素而不是内联元素来做到这一点。 现在 text-align 属性将无济于事,因为你必须将它们浮动到左侧。 现在,由于左侧浮动,你将无法将它们保持居中。
这就是我文章的最初目的,解决那个问题。 但现在似乎我的原始解决方案对 IE 不友好,出于某种奇怪的原因,所以我更新了以利用 display: inline 的想法。 这有效,但如果我这样做……那么你的解决方案也一样有效。
所以你可以看到,这开始有点失去重点了 =P
我明白了。 我了解那种感觉 :)
谢谢!
@david walsh:我看了你的代码,不得不说在网站可访问性方面它看起来不太好。 从可访问性的角度来看,使用列表进行导航很有意义。
@Stefan:从可访问性的角度来看? 为什么? 通过向我的网站添加 JavaScript 库(就像大多数网站一样),我更喜欢不使用不必要的代码(以 UL、OL 和 LI 的形式)。
@David:我使用列表进行可访问性方面有很好的经验。 但是我必须承认它不是必需的代码,导航也可以在没有列表的情况下工作。 这只是一个观点。
我想也许 stefan 正在说,当 CSS 关闭(屏幕阅读器样式)时,使用无序列表技术的菜单会还原为常规列表(带有项目符号),这是一种很好的降级方式。
我现在明白你的意思了 - 我会在 CSS Naked Day 把它牢记在心。 在那之前,我将继续我的反对导航列表的运动。
@David:我同意 ;-)
我个人以前没有见过
display: table;
的用法……听起来很有用!
@David - 除了 Chris 指出的 css 关闭点之外,我还建议它比其他建议更语义化,因为对于很多导航,你只需要
ul 和 li
,它可以节省使用其他 div 等。你让我很容易。 谢谢。 你能帮我一下,有时候当我制作一些浮动的 id 时,它会跑到下面。 不知道那里发生了什么。 请帮我一下。
@Prap:如果你有浮动项,并且父元素的宽度变得太小而无法并排包含它们,它将把它们“推到下面”。 为防止这种情况,只需确保父元素不会变得太小而导致这种情况发生,方法是设置一个足够大的静态宽度或最小宽度。
嗨 PraP
为了防止“跑到下面”,我使用
white-space nowrap。
如果有人使用字体大小 +++++,则会出现水平滚动条,但他可以阅读内容。
也许这不是解决此问题的完美方法,但我知道如果有人需要字体大小 +++++,他大多数时候都在使用屏幕阅读器。
或者他大多数时候都知道存在水平滚动条。
此致
Monika
好的… 我正在处理类似的事情… 但是尝试涵盖所有方面并确保最广泛的使用,这失败了(似乎 CSS 有一个小的缺陷,你可以很好地做 A、B 或 C… 当你想做 A 和 B 时就会变得困难)。
所以目标是:使用标准列表来保存基于文本的链接,并生成一个水平条。
从那里,将条形居中,以便链接出现在中间。
使所有链接都具有固定的宽度,以 EM 为单位。
允许“链接高度”根据需要增加(文本将换行)。
如果一行中有太多链接,或者宽度缩短,那么内容应该下降到下一行,并继续这样做。
这意味着无论宽度如何,菜单的内容始终居中且可见。
基于文本意味着稍微更好的 SEO 和可访问性。
EM 宽度设置意味着改变文本大小允许缩放,更好的可访问性。
允许灵活的高度意味着我们可以避免担心过长的链接标题(3 或 4 个字),因为菜单将适应。
问题是,当我尝试这样做时,我总是失败。
我能做到的最接近的方法是使用 tabe/t-row/t-cell(有人注意到如果你设置 display:block,然后设置 display: table… IE6 似乎对表格有反应)… 但这会大幅度地改变行为,或者在每个列表项的前面留下一个空隙。
所以,如果有人成功了,或者想玩,请告诉我 :)
另外,圣诞快乐(对于那些庆祝它的人)。
@Autocrat: 这是对你的问题的尝试
https://css-tricks.org.cn/examples/CenteredTextLinks/
它似乎工作正常,但它表现出一些半奇怪的行为。例如,在 FF 中,当你扩展到链接框换行到下一行时,它工作正常,但当你减小尺寸返回时,它不会向上展开。很奇怪,但可能不是那么大不了的事。
嗨,Chris,你的代码在 Opera、Safari 和 Firefox 中似乎工作正常,但 IE6 或 7 似乎都不喜欢它,我不确定这是否是我的代码的问题,但我非常渴望让它工作!任何帮助将不胜感激。我没有“menu-outer”div,只有 table wrap div。我还在使用 Joomla 1.5,所以列表项是生成的,而不是硬编码的。
#listwrap {
display: table; /* 允许居中工作 */
margin: 0 auto;
}
#topmenu {
height:40px;
}
#topmenu ul.menu {
min-width: 40px; /* 为了适应 1 - 2 个列表项 */
list-style: none;
}
#topmenu li {
display: inline;
}
提前感谢大家提供的任何评论或帮助。
@LukeR: 你是否有我们可以查看的 URL 来查看问题?是居中问题,还是其他问题?首先,IE 可能不会遵守该最小宽度,因此您可能需要在那里做一些其他事情。
感谢您的快速回复,Chris,我刚刚在我的临时模板上发布了 live 网站
http://www.nukedesign.co.uk/dev/sitetest/
尝试使用 IE6/7 的最小宽度 hack(你的,实际上!),但这似乎也无法解决它。
#topmenu ul.menu {
min-width: 40px;
max-width:880px;
width:expression(document.body.clientWidth 882? "880px" : "auto");
list-style: none;
}
如你所见,它在所有非 IE 浏览器中工作正常。
我也在为 mootools 遇到问题,除了 Safari 和 FF 之外,但这不是你的领域;)
再次感谢您提供的任何帮助。
Luke
@LukeR: 是的,我可以看到菜单在 IE6 中没有居中。它只是偏向左侧,看起来并不太糟糕。对于这种类型的菜单,您可能想要考虑放弃无序列表,而使用一系列锚链接。这样,您只需拥有一个包装 div,并将文本对齐设置为居中,它将正常工作。
感谢你,Chris,不幸的是,这将是一个 Joomla 模板,UL 是由 Joomla 生成的,所以没有太多我可以做的事情,我想我必须换个新样子!感谢你的所有帮助!
此致敬礼,
Luke
这个 CSS hack 在 FF3 和 IE7 上对我来说非常有效,还没有在 IE6 中测试过,但我将测试。但是,为了使它在 IE7 中居中,我不得不进行一些额外的调整,因为我遇到了与 LukeR 类似的问题。
以下是我的操作
#menu-outer {
height: 84px;
}
.hortable {
display: table; /* 允许居中工作 */
margin: 0 auto;
}
ul#horizontal-list
{
min-width: 50px;
list-style: none;
text-align:center; /* 这是我进行的调整 */
}
ul#horizontal-list li {
display: inline;
}
这似乎是一种非常复杂的方式来处理事情。我的一个网站上有一个居中的导航栏,我所做的只是
ul#menu {text-align:center; list-style-type:none;}
ul#menu li {display:inline;}
显然,比这还要多一些样式,但这似乎可以做到让它与页面中间对齐。
我知道关于 css 的事情,我只想说我真的很喜欢你关于旅行行李牌的背景页面,它可以被用作 MySpace 布局,供人们下载、个性化并上传到他们的个人资料…我知道我会的。
就是这样。我在搜索时找到了你的网站,当时我在寻找一个在我的脑海中创建的 MySpace 菜单,并开始寻找一些类似的东西。
感谢您抽出时间阅读。
Critter
您好,
我在实现你居中的 li 时遇到了一些问题。我假设我的问题是,我没有使用文本,而是使用 BG 图像来表示每个 li。让我解释一下
我正在做一个网站,它最终将拥有动态驱动的导航(通过后端编辑)。我一直使用以下代码作为我的导航标准,它非常有效
<div id="navcontainer">
<ul>
<li class="navexample01"><a href="#"></a></li>
<li class="navexample02"><a href="#"></a></li>
<li class="navexample03"><a href="#"></a></li>
<li class="navexample04"><a href="#"></a></li>
</ul>
使用这段代码,我附上了以下 CSS(通用)
#navcontainer ul {
display:block;
background-image: url(images/example.jpg);
background-repeat: no-repeat;
background-position: left top;
}
.navexample01 a {
background-image: url(images/exampleoff.jpg);
background-repeat: no-repeat;
background-position: left top;
display: inline-block;
float: left;
width: 50px;
height: 25px;
}
.navexample01 a:hover {
background-image: url(images/exampleon.jpg);
background-repeat: no-repeat;
background-position: left top;
display: inline-block;
float: left;
width: 50px;
height: 25px;
}
依此类推。我为每个类提供了它自己的背景图像以及悬停图像。大多数情况下,每个按钮都有不同的宽度,这就是为什么我不能对所有 li 进行通用大小调整的原因。我在 UL 本身上使用 BG 图像来避免 IE6 对悬停给予的“闪烁”效果。
无论如何,我知道我不能使用 float left 来使列表项居中。但如果我不使用 [float],它就不会显示出来!
你的帮助将不胜感激!
哦,我意识到我使用了 *you're* 而不是 *your*。愚蠢的打字错误!;)
我只花了半天时间,但我弄明白了!厉害!我甚至不确定是否有人发布了答案,但不知何故,我设法让它工作了,跨浏览器!耶!
我不能发布我的结果,因为我正在为这个特定项目严格的截止日期!如果你想让我发布我的结果,我当然可以按要求发布!
感谢所有伟大的想法!我使用你的一些 CSS 技巧来让它工作!:D
6 年后仍然是一篇有用的文章!
干杯!喜欢 CSS-Tricks 最近是如何在 Stackoverflow 上排名如此靠前的… 保持良好的工作,Chris,有一天我会请你喝一杯!
哦,我看到使用了表格。太糟糕了!>:( 这个解决方案不是跨浏览器友好的。
如果你使用的是 display:block 而不是 display:inline,你会怎么做?
在列表项上使用
display: inline
的一个问题是,由于它们是内联元素,元素之间的空格将转换为与字体常规空格宽度相同的空格。这在某些设计中是不可感知的,但当你元素之间有边框时,事情就会变得很糟糕。为了解决这个问题,有几个选择。
你可以将 font-size:0 设置在
<
ul> 上,并将 font-size: whatever 设置在 上,这样间隙将被渲染为 0 像素宽。
你可以在 HTML 中的 之间移除所有空格。
你的 CSS 代码对我想居中的下拉菜单有效,但当我添加图像到页面的顶部时,菜单又回到左侧了,我做错了什么?
看起来我们根本无法摆脱表格。好技巧,它对我的网站开发有效。以前从未见过,非常干净的解决方案!
完美 (Y)