Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make element width stretch to fit its children when element's parent has overflow: auto;

Tags:

css

overflow

In this simplified example, I have a bookcase with books sitting on bookshelves. The bookcase is the outermost element with a defined width. The books on a bookshelf are supposed to appear left to right without wrapping. The bookshelf is supposed to stretch its width to show all the books on its shelf. All bookshelves need to be the same width, the width of the widest bookshelf.

My HTML:

<div class="bookcase">
    <div class="bookshelf">
        <div class="book">
        <div class="book">
        <div class="book">
    </div>
    <div class="bookshelf">
        <div class="book">
        <div class="book">
        <div class="book">
        <div class="book">
    </div>
    <div class="bookshelf">
        <div class="book">
    </div>
</div>

My CSS:

.bookcase {
    width: 40%;
    height: 300px;
    margin: 0 auto;
    background: lightgrey;
    overflow-x: auto;
}
.bookshelf {
    background: lightgreen;
    white-space: nowrap;
}
.book {
    display: inline-block;
    height: 60px;
    width: 60px;
    background: pink;
}

jsFiddle demo

The problem with the current code is that when the bookcase width is smaller than the longest bookshelf and the bookcase makes the overflow scrollable, the bookshelf elements don’t stretch to fit all the books. Currently the shelves appear to be defining their width equal to the parent, the bookcase.

These pictures illustrate the problem. This is how the bookcase looks normally, which is fine:

looks good scrolled left with narrow bookcase or looks good with wide bookcase

But when you scroll right when the bookcase is narrow, the bookshelves’ green background is cut off, instead of reaching to the right side of the last red book:

bookshelf background is missing when you scroll right with narrow bookcase

How can I make the bookshelves take the full width of the overflowed element, rather than the width of the bookcase parent container?

like image 864
BigMacAttack Avatar asked Aug 15 '13 20:08

BigMacAttack


People also ask

How can I make my child's width bigger than my parents?

A child div can also be wider than its parent by utilizing different positioning such as absolute or fixed positioning. Different results can occur depending on the specified position of the parent div but as long as the element is either absolute/fixed or contains a specified width, it will grow outside the parent.

How do you make a child div full width of a parent?

The solution is to simply not declare width: 100% . The default is width: auto , which for block-level elements (such as div ), will take the "full space" available anyway (different to how width: 100% does it). Save this answer.

How do I make a div fit my parents?

If you want the child divs to fit the parent size, you should put a margin at least of the size of the child borders on the child divs ( child. margin >= child. bordersize ).

How do you make a child div take full height of parent div?

Example 2: The second way to achieve this by using align-items property in the parent div to 'stretch'. It makes every . child-div 100% height of it's parent height.


2 Answers

Adding display:table on the .bookcase element does almost what you need.

FIDDLE

The only difference is that instead of the scrollbars appearing when the longest bookshelf > 60% of the viewport width, they appear when the longest bookshelf > 100% of the viewport width.

But the problem with the disappearing background is gone.

like image 23
Danield Avatar answered Oct 07 '22 20:10

Danield


Thanks to Javalsu, Hashem Qolami, and Danield for helping me find a suitable solution. Indeed, the trick is to utilize inherent display properties of tables. The solution I found was to wrap the .bookcase in another element (I'm calling this wrapper element the .wall). Move the overflow: auto; with the static height: and width: properties from the .bookcase to the .wall, and add display: table; and width: 100%; to the .bookcase.

The display: table; property is needed for when overflow is scrolling, and the width: 100%; is needed for when the overflow is not scrolling.

My New HTML:

<div class="wall">
    <div class="bookcase">
        <div class="bookshelf">
            <div class="book"></div>
            <div class="book"></div>
            <div class="book"></div>
        </div>
        <div class="bookshelf">
            <div class="book"></div>
            <div class="book"></div>
            <div class="book"></div>
            <div class="book"></div>
        </div>
        <div class="bookshelf">
            <div class="book"></div>
        </div>
    </div>
</div>

My New CSS:

.wall {
    width: 60%;
    height: 300px;
    margin: 0 auto;
    background: lightgrey;
    overflow: auto;
}
.bookcase {
    display: table;
    width: 100%;
}
.bookshelf {
    background: lightgreen;
    white-space: nowrap;
}
.book {
    display: inline-block;
    height: 60px;
    width: 60px;
    background: pink;
}

jsFiddle demo

Result:
looks good when scrolled or looks good when no scroll

like image 83
BigMacAttack Avatar answered Oct 07 '22 22:10

BigMacAttack