Stop floating divs from wrapping

119,692

Solution 1

The CSS property display: inline-block was designed to address this need. You can read a bit about it here: http://robertnyman.com/2010/02/24/css-display-inline-block-why-it-rocks-and-why-it-sucks/

Below is an example of its use. The key elements are that the row element has white-space: nowrap and the cell elements have display: inline-block. This example should work on most major browsers; a compatibility table is available here: 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>

Solution 2

You want to define min-width on row so when it browser is re-sized it does not go below that and wrap.

Solution 3

After reading John's answer, I discovered the following seemed to work for us (did not require specifying width):

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

Solution 4

The only way I've managed to do this is by using overflow: visible; and width: 20000px; on the parent element. There is no way to do this with CSS level 1 that I'm aware of and I refused to think I'd have to go all gung-ho with CSS level 3. The example below has 18 menus that extend beyond my 1920x1200 resolution LCD, if your screen is larger just duplicate the first tier menu elements or just resize the browser. Alternatively and with slightly lower levels of browser compatibility you could use CSS3 media queries.

Here is a full copy/paste example demonstration...

<?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>
Share:
119,692
Nicholas
Author by

Nicholas

Updated on April 18, 2020

Comments

  • Nicholas
    Nicholas about 4 years

    I want to have a row of divs (cells) that don't wrap if the browser is too narrow to fit them.

    I've searched Stack, and couldn't find a working answer to what I think should be a simple css question.

    The cells have specified width. However I don't want to specify the width of the row, the width should automatically be the width of its child cells.

    If the viewport is too narrow to accomodate the rows, then the div should overflow with scrollbars.

    Please provide your answer as working code snippet, as I've tried a lot of the solutions I've seen elsewhere (like specify width: 100% and they don't seem to work).

    I'm looking for a HTML/CSS only solution, no 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>

    At the moment I'm actually hard coding the width of the row to a really big number.

  • Cees Timmerman
    Cees Timmerman almost 11 years
    Add <!DOCTYPE html> or <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> to the top of the HTML to have IE not default to quirks mode.
  • Nick.McDermaid
    Nick.McDermaid over 9 years
    When I use the upvoted answer and replace width:100% with width:1000px it works for me
  • John
    John over 9 years
    @Nick.McDermaid I used 20K pixels for a reason, with 4K screens coming out you know there will eventually be 8K and so on, so best to work with an insanely high number to keep it working for those extra years until screens are more high-resolution than life itself. ;-)
  • Nick.McDermaid
    Nick.McDermaid over 9 years
    Understood... I'm just happy I got it to stop wrapping. CSS-it drives me nuts even with F12 tools. I don't know how anyone got anything done without them.
  • Danon
    Danon over 9 years
    This'd work even with floats. I think that's the real answer.
  • TryHarder
    TryHarder about 9 years
    This fixed a problem I was having with draggable divs on the iphone. When the divs had more than one word in them and they were dragged to the edge of the screen the div would wrap so that there was a word on either line. Anyway overflow: visible; white-space: nowrap; Did the trick for me. Thanks!
  • Steve Hibbert
    Steve Hibbert about 9 years
    Note: I had my cell-type divs set up with float:left, and this forced the computed style to be block, instead of inline-block. Took a while to figure out, so thought it best to share that.
  • dlchambers
    dlchambers about 9 years
    Agree with @Danon - this works whereas the inline-block introduced vertical alignment issues.
  • Andy
    Andy over 8 years
    This doesn't work with the last cell being float: right, does it?
  • Andy
    Andy over 8 years
    This isn't really an example of how to keep floated divs from wrapping -- you just unfloated the cells. I have a layout with some left and right floats, so I can't do away with the floats to solve the wrapping issue.
  • Andy
    Andy over 8 years
    It worked because he unfloated the cells. Not really a solution to keep actually floating divs from wrapping
  • Calvin
    Calvin over 8 years
    Haha, fair enough. It's a pedantic distinction, but you are right. I didn't solve "stop floated divs from wrapping", I solved the asker's real question "how do I make my layout work". To answer the former: I'm reasonably sure there is no way to prevent floated divs from wrapping. Just like the asker, you will need to find a different way to encode the layout you are describing.
  • gyo
    gyo over 8 years
    For future reference: using a huge width/height is highly inefficient because the browser still stores an unneeded big box into memory. Set the container to white-space: nowrap; and the children to display: inline-block; as already said in other answers (or fall back to display: table; and display: table-cell;).
  • theflowersoftime
    theflowersoftime about 8 years
    main > * > * {background-color: #000;} O_o
  • Calvin
    Calvin over 7 years
    Depends on your needs. This does stop floated divs from wrapping when the page is resized, but the asker stated "I don't want to specify the width of the row, the width should automatically be the width of its child cells". Manual width specification requires some duplicated work, since you need to compute the total width of the row. Even worse, if your cells are variable width (say, because they are sized to a line of text inside them) then computing the total may be impractical or impossible.
  • Teodor Sandu
    Teodor Sandu almost 7 years
    -1; This goes against what the OP specifically stated in his question, namely NOT having to specify width. +1 to Calvin's comment above.
  • caiosm1005
    caiosm1005 over 5 years
    display:absolute is not valid CSS
  • Vaaljan
    Vaaljan over 3 years
    Probably meant position
  • user2377141
    user2377141 over 3 years
    once "white-space: no-wrap" added to the container, you might want to add "white-space: normal;" to the children elements or else their content will overflow their own box.