Sasha
Sasha

Reputation: 1072

An inline-block div with "white-space: normal" exceeds the width of a parent with "white-space: nowrap"

I'm trying to position a few elements in a row, so that they all fit in the width of the container. To prevent them from word-wrapping I added "white-space: nowrap" to the parent, and added "white-space: normal" to the children to allow them to wrap the text (as desired).

The problem is that with this configuration the right most child sometimes exceeds the width of the parent.

expected vs actual

HTML:

<div id="container">
    <div class="child">
        child 1
    </div>
    <div class="child">
        child 2 text that might be long enough to wrap, but still exceed the parent
    </div>
</div>

CSS:

#container {
    white-space: nowrap;
    width: 200px;
    background: yellow;
    border: 1px solid brown;
    padding: 5px;
}

.child {
    display: inline-block;
    border: 2px solid red;
    vertical-align: top;
    white-space: normal;
}

http://jsfiddle.net/7e5TU/1/ (change the length of the text if the problem doesn't appear straight away).

I know that I can solve it with a table, and probably with a float on the left child, and "overflow: hidden" on the right, but I see no reason why this should not work.

Could anyone provide some insights? I'd mostly love to understand what in the box model causes this behavior. Thanks!

Upvotes: 8

Views: 6683

Answers (3)

Tom Berthold
Tom Berthold

Reputation: 552

You can do this with CSS display:table. This way no sizing details are needed. It ensures the elements stay in a row and the text will wrap perfectly to the width of the parent container.

HTML

<div class='container'>
  <div class='field'>
    <div class='data'>
      child 1
    </div>
  </div>
  <div class='field'>
    <div class='data'>
      child 2 text that might be long enough to wrap, but still exceed the parent
    </div>
  </div>
</div>

CSS

.container {
  display: inline-table;
  border-spacing: 4px;
  background: yellow; border: 1px solid brown;
  padding: 5px;
}
.field {
  display: table-cell;
}
.data {
  border: 2px solid red;
  padding: 3px;
}

Upvotes: 0

Mathias
Mathias

Reputation: 5672

If you are willing to use flexbox (https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes) you could do it like this: http://jsfiddle.net/7e5TU/6/

HTML

<div id="container">
    <div class="child1">
        child 1
    </div><div class="child2">
        child 2 text that might be long enough to wrap, 
        but still exceed the parent
    </div>
</div>

CSS

#container {
    width: 200px;
    background: yellow;
    border: 1px solid brown;
    padding: 5px;
    display: flex;
    flex-direction: row
}

.child1, .child2 {
    display: block;
    border: 1px solid red;
    vertical-align: top;
}

.child1 {
    min-width: 50px;   
}

Upvotes: 1

Aamir Shahzad
Aamir Shahzad

Reputation: 6834

I agree with @hashem That's the expected behavior. By using white-space: nowrap; for the parent, you've collapsed the whitespaces between inline(-block) elements. white-space treats the children, not the element itself.

Well if you still need a fix you can add width to second child to make it fit inside container.

fiddle

e.g.

.child2
{
    width: 70%;
}

Upvotes: 1

Related Questions