停止浮动的div换行

89
我想要一行div(单元格),如果浏览器窗口太窄而无法容纳它们,它们不会换行。我在Stack上搜索过,但找不到一个可以工作的答案,我认为这应该是一个简单的CSS问题。 这些单元格有指定的宽度。但是,我不想指定行的宽度,行的宽度应该自动为其子单元格的宽度。 如果视口太窄以容纳行,则应使用滚动条溢出div。 请提供您的答案作为工作代码片段,因为我已经尝试了很多我在其他地方看到的解决方案(例如指定width:100%,它们似乎不起作用)。 我正在寻找仅限HTML / CSS的解决方案,没有JavaScript。

.row {
  float: left;
  border: 1px solid yellow;
  width: 100%;
  overflow: auto;
}
.cell {
  float: left;
  border: 1px solid red;
  width: 200px;
  height: 100px;
}
<div class="row">
  <div class="cell">a</div>
  <div class="cell">b</div>
  <div class="cell">c</div>
</div>

目前我正在将行的宽度硬编码为一个非常大的数字。


1
以下答案有没有一个对您有用?我尝试了所有的方法都没有成功。 - John Fitzpatrick
我刚刚尝试了所有的答案,但都没有解决我的问题。问题是我需要将两个左浮动的div居中,并防止右侧的div在窗口调整大小后被推到左侧下方。 - Bashevis
@Nicholas 我认为我的示例恰好符合你的要求,我今天遇到了同样的问题。下拉菜单溢出但第一层没有换行。 - John
6个回答

112
CSS属性display: inline-block旨在解决这个需求。您可以在此处阅读一些相关信息:http://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/ 以下是其使用示例。关键元素是row元素具有white-space: nowrap,而cell元素具有display: inline-block。此示例应适用于大多数主要浏览器; 兼容性表可在此处找到:http://caniuse.com/#feat=inline-block
<html>
<body>
<style>

.row {
    float:left;
    border: 1px solid yellow;
    width: 100%;
    overflow: auto;
    white-space: nowrap;
}

.cell {
    display: inline-block;
    border: 1px solid red;
    width: 200px;
    height: 100px;
}
</style>

<div class="row">
    <div class="cell">a</div>
    <div class="cell">b</div>
    <div class="cell">c</div>
</div>


</body>
</html>

1
在 HTML 顶部添加 <!DOCTYPE html><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">,以使 IE 不默认使用怪异模式。 - Cees Timmerman
4
注意:我之前将单元格的div设置为float:left,这导致计算样式变为block,而不是inline-block。花了一段时间才弄清楚,所以觉得最好分享一下。 - Steve Hibbert
最后一个单元格设置为 float: right 不行吗? - Andy
3
这并不是一个如何防止 浮动 div 换行的例子——你只是取消了单元格的浮动。我有一个布局,其中包含一些左浮动和右浮动,所以我不能取消浮动来解决换行问题。 - Andy
哈哈,说得对。这是一个吹毛求疵的区别,但你是正确的。我没有解决“如何阻止浮动div换行”的问题,而是解决了提问者真正的问题“如何使我的布局工作”。回答前者:我相当确定没有办法防止浮动的div换行。就像提问者一样,您需要找到一种不同的方式来编码您描述的布局。 - Calvin
1
一旦在容器中添加了“white-space: no-wrap”,您可能希望将“white-space: normal;”添加到子元素中,否则它们的内容将溢出其自身的框。 - user2377141

33

您希望在行上定义min-width,以便在调整浏览器大小时,它不会低于该值并换行。


1
这也适用于浮点数。我认为这才是真正的答案。 - Danon
2
同意@Danon的观点 - 这个方法有效,而使用inline-block会引起垂直对齐问题。 - dlchambers
1
根据您的需求而定。这确实可以防止浮动的div在页面调整大小时换行,但提问者表示“我不想指定行的宽度,宽度应自动为其子单元格的宽度”。手动指定宽度需要一些重复的工作,因为您需要计算行的总宽度。更糟糕的是,如果您的单元格具有可变宽度(例如,因为它们被调整为其中的文本行),则计算总宽度可能是不切实际或不可能的。 - Calvin
1
-1;这与OP在问题中明确指出的不需要指定宽度相矛盾。赞成Calvin上面的评论。 - Teodor Sandu

5

在阅读了John的答案后,我发现以下方法似乎适用于我们(不需要指定宽度):

<style>
.row {
    float:left;
    border: 1px solid yellow;
    overflow: visible;
    white-space: nowrap;
}

.cell {
    display: inline-block;
    border: 1px solid red;
    height: 100px;
}
</style>

<div class="row">
    <div class="cell">hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello </div>
    <div class="cell">hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello </div>
    <div class="cell">hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello </div>
</div>

这解决了我在 iPhone 上使用可拖动 div 时遇到的问题。当 div 中有多个单词并将其拖到屏幕边缘时,div 将换行,以便每行都有一个单词。无论如何 overflow: visible; white-space: nowrap; 对我很有用。谢谢! - TryHarder
4
因为他取消了单元格的浮动,所以它起作用了。但这并不是一个真正解决浮动 div 元素换行问题的方法。 - Andy

2
我唯一能想到的解决方法是在父元素中使用overflow: visible;width: 20000px;。据我所知,CSS level 1 没有实现这个功能,我拒绝采用CSS level 3 的所有可能方法。下面的示例有18个菜单超出了我的1920x1200分辨率的LCD屏幕,如果你的屏幕更大,只需复制第一层菜单元素或调整浏览器大小即可。另外,稍微降低浏览器兼容性,您可以使用CSS3媒体查询。以下是完整的演示示例...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>XHTML5 Menu Demonstration</title>
<style type="text/css">
* {border: 0; box-sizing: content-box; color: #f0f; font-size: 10px; margin: 0; padding: 0; transition-property: background-color, background-image, border, box-shadow, color, float, opacity, text-align, text-shadow; transition-duration: 0.5s; white-space: nowrap;}
a:link {color: #79b; text-decoration: none;}
a:visited {color: #579;}
a:focus, a:hover {color: #fff; text-decoration: underline;}
body {background-color: #444; overflow-x: hidden;}
body > header {background-color: #000; height: 64px; left: 0; position: absolute; right: 0; z-index: 2;}
body > header > nav {height: 32px; margin-left: 16px;}
body > header > nav a {font-size: 24px;}
main {border-color: transparent; border-style: solid; border-width: 64px 0 0; bottom: 0px; left: 0; overflow-x: hidden !important; overflow-y: auto; position: absolute; right: 0; top: 0; z-index: 1;}
main > * > * {background-color: #000;}
main > section {float: left; margin-top: 16px; width: 100%;}
nav[id='menu'] {overflow: visible; width: 20000px;}
nav[id='menu'] > ul {height: 32px;}
nav[id='menu'] > ul > li {float: left; width: 140px;}
nav[id='menu'] > ul > li > ul {background-color: rgba(0, 0, 0, 0.8); display: none; margin-left: -50px; width: 240px;}
nav[id='menu'] a {display: block; height: 32px; line-height: 32px; text-align: center; white-space: nowrap;}
nav[id='menu'] > ul {float: left; list-style:none;}
nav[id='menu'] ul li:hover ul {display: block;}
p, p *, span, span * {color: #fff;}
p {font-size: 20px; margin: 0 14px 0 14px; padding-bottom: 14px; text-indent: 1.5em;}
.hidden {display: none;}
.width_100 {width: 100%;}
</style>
</head>

<body>

<main>
<section style="height: 2000px;"><p>Hover the first menu at the top-left.</p></section>
</main>

<header>
<nav id="location"><a href="">Example</a><span> - </span><a href="">Blog</a><span> - </span><a href="">Browser Market Share</a></nav>
<nav id="menu">
<ul>
<li><a href="" tabindex="2">Menu 1 - Hover</a>
<ul>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
<li><a href="" tabindex="2">Menu 1 B</a></li>
</ul>
</li>
<li><a href="" tabindex="2">Menu 2</a></li>
<li><a href="" tabindex="2">Menu 3</a></li>
<li><a href="" tabindex="2">Menu 4</a></li>
<li><a href="" tabindex="2">Menu 5</a></li>
<li><a href="" tabindex="2">Menu 6</a></li>
<li><a href="" tabindex="2">Menu 7</a></li>
<li><a href="" tabindex="2">Menu 8</a></li>
<li><a href="" tabindex="2">Menu 9</a></li>
<li><a href="" tabindex="2">Menu 10</a></li>
<li><a href="" tabindex="2">Menu 11</a></li>
<li><a href="" tabindex="2">Menu 12</a></li>
<li><a href="" tabindex="2">Menu 13</a></li>
<li><a href="" tabindex="2">Menu 14</a></li>
<li><a href="" tabindex="2">Menu 15</a></li>
<li><a href="" tabindex="2">Menu 16</a></li>
<li><a href="" tabindex="2">Menu 17</a></li>
<li><a href="" tabindex="2">Menu 18</a></li>
</ul>
</nav>
</header>

</body>
</html>

当我使用被投票为最佳答案的方法并将 width:100% 替换为 width:1000px,它适用于我。 - Nick.McDermaid
@Nick.McDermaid 我使用了20K像素是有原因的,随着4K屏幕的问世,你知道最终会出现8K等更高分辨率的屏幕,所以最好使用一个疯狂高的数字来保持它在未来几年内能够正常工作,直到屏幕比生命本身还要高分辨率。;-) - John
明白了...我只是很高兴它不再换行了。CSS让我抓狂,即使使用F12工具也是如此。我不知道有人是怎么做到没有它们完成工作的。 - Nick.McDermaid
1
供日后参考:使用巨大的宽度/高度非常低效,因为浏览器仍然会将一个不需要的大盒子存储到内存中。将容器设置为 white-space: nowrap;,并将子元素设置为 display: inline-block;,如其他答案中已经提到的(或者回退到 display: table;display: table-cell;)。 - gyo
主要 > * > * {背景颜色:#000;} O_o - theflowersoftime

0
对我来说(使用bootstrap),唯一有效的方法是在最后一个单元格上设置display:absolute;z-index:1

1
"display:absolute" 不是有效的 CSS。 - caiosm1005
可能是指位置。 - Vaaljan

-1

我曾经遇到过一个类似的问题,其中一个有界区域由一个float:left块中的图像和一个非浮动文本块组成。该区域具有流体宽度。根据设计,文本将沿着图像的右侧包裹起来。问题是,文本以<h2>标签开头,其中第一个单词是微小的单词“From”。当我调整窗口大小到较小的宽度时,对于一定范围的宽度,非浮动文本将只留下顶部包装区域的单词“From”,其余文本被挤压在浮动块下面。我的解决方案是通过用这个代码替换后面的空格,<span style="opacity:0;">x</span> ,使第一个单词的标签变大。效果是使第一个单词不再是“From”,而是“FromxNextWord”,其中“x”是不可见的,看起来像一个空格。现在我的第一个单词足够大,不会被文本块抛弃。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接