Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parent element incorrectly calculates the width of their children

Tags:

html

css

Please look at the demo: http://jsfiddle.net/7wwobsqq/1/

<div class="parent">
    <div class="child"></div>
    <div class="child"></div>
</div>

.parent {
    max-width: 300px;
    background: grey;
    overflow: hidden;
}

.child {
    float: left;
    width: 200px;
    height: 200px;
    border: 1px solid #000;
    margin-bottom: 10px;
}

My problem is that the parent element computes its width, without paying attention to the fact that the blocks are on different lines.

Then for this example, I would like to parent has been narrowed to the maximum width of the block. Also, if the children are able to fit on one line, they should be there. To help you understand what I mean, take a look at the screenshots: http://s21.postimg.org/ioldq2blj/stack_Overflow.jpg

Currently I am using ul->li elements, not div's, as on jsfiddle page, but in this case their behaviors are equally.

Thanks for the comments.

Here are additional examples. In the first case, we see the two elements aligned. In the second case, the second child is moved down, because the parent element has max-width. We got an empty space on the right. Screenshot - http://s4.postimg.org/p4h4bj86l/stack_Overflow2.jpg http://jsfiddle.net/7wwobsqq/8/ http://jsfiddle.net/7wwobsqq/9/

<ul class="parent">
   <li class="child first">
   </li>
   <li class="child second">
   </li>
</ul>

.parent {
    border: 1px dashed #ccc;
    float: left;
    min-width: 333px;
    max-width: 500px;
    overflow: hidden;
}

.child {
    margin: 2px;
    float: left;
    display: inline-block;
    background-color: rgb(255, 216, 87);
}

.first {
    width: 126px;
    height: 127px;
}

.second {
  width: 207px;
  height: 122px;
}
like image 739
Antoni Bertel Avatar asked Oct 19 '22 09:10

Antoni Bertel


2 Answers

Your .parent div is always going to be 100% width, becuase that is what happens when you have an element that is display: block. It will take up the width of it's parent element. Right now max-width is controlling the width of your .parent element, because it wants to fill it's parent, but it can't.

You probably want something like this.

Get rid of overflow: hidden on your .parent, it's unnecessary.

Also, you need to set display: inline-block on both the .parent and .child elements. This gives you all the styling perks of a block element, but tells it that you need it to be on the same line as it's siblings.

like image 122
arjabbar Avatar answered Oct 27 '22 20:10

arjabbar


Add display: inline-block; to the .parent, and remove float: left from .child, and you'll get your expected behavior:

Fiddle


Here's why your code doesn't work:

W3C defines the algorithm for determining the dimensions of HTML elements. Here, .parent is a "block-level, non-replaced element in normal flow."

First, a tentative width is calculated ignoring the max-width property. For a block-level element, this would be the width of its parent minus margins – in this case the width of the document body.

If this width is greater than max-width, then max-width becomes the width – in this case, 300px.

It's as simple as that. Adding a max-width to a div automatically sets the div to be that width, regardless of content. You can see that in this Fiddle (no content) as well as this Fiddle (content overflowing the parent).


Here's why my code works:

Adding display: inline-block; to the .parent makes it an "inline-block, non-replaced element in normal flow."

Since there's not a defined width, the shrink-to-fit algorithm is now used, which (true to its name), shrinks the container to fit its content.

like image 25
Rick Hitchcock Avatar answered Oct 27 '22 19:10

Rick Hitchcock