不折行的长下拉菜单项及背后的原理
把多级导航做成下拉菜单的形式是现在的通用设计。
仅使用CSS实现一个下拉菜单是很简单的,主要思路就是使用绝对定位。
但是在下拉菜单项的内容较长,准确地说是长度超过上一级菜单项的内容长度时,下拉菜单项会折行。原本整齐漂亮的下拉菜单一下子就变丑了。

要内容长的下拉菜单不折行,实现起来也很简单,只需要设置下拉部分的white-space属性为nowrap或者pre即可。
说得有些抽象,下面是示例。
See the Pen 不折行的长下拉菜单项 by xingzhi (@xingzhi) on CodePen.
实现方法也说了,示例也看了,如果只想知道如何实现,看到这儿就不需要继续往下看了。
而如果心里还有两个疑问:为什么会折行?为什么设置了white-space后又不折行了?那么就继续往下看吧。
首先来一点理论。
理论
在CSS的基本盒模型中,水平方向的长度一共涉及有7个属性:margin-left、border-left、padding-left、width、padding-right、border-right和margin-right。其中有3个属性的值可以设置为auto:margin-left、width和margin-right。除了width的默认值是auto外,其他属性的默认值都是0。
在渲染过程中,这7个属性的值需要满足一个条件
margin-left + border-left + padding-left + width + padding-right + border-right + margin-right = 元素的包含块的宽度
当这个等式不成立时,margin-right会被重置为auto,然后自动调整从而使等式成立。
如何确定元素的包含块可以看CSS包含块。
理论到此为止,下面来说一说上面的两个疑问。
为什么会折行
折行的原因很简单:下拉菜单项的宽度超过了其包含块的宽度,内容(width的值为auto)被自动调整从而使上面的等式成立。
在上面的示例中,下拉部分是通过绝对定位实现的,它的包含块就是上一级菜单的内边距块。同时,width属性的值为auto,渲染时width属性就会自动调整以满足上面的等式,当内容长度超过width属性的值时就会折行。
为什么又不折行了
理解了折行的原因,不折行的原因就简单多了。
通过设置下拉菜单项内容不可以折行,width属性的值被自动调整为在一行里包含所有内容,进一步引发margin-right被重置为auto,然后自动调整以使上面的等式成立。