Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Flexbox Containers, PRE tags and managing Overflow


:P
On this page:

I've been moving a bunch of old markup over to Flexbox layout recently, because it makes so many things so much easier to deal with. One place I did this with is this blog – previously I was using a left float with absolutely positioned headers and containers, which worked Ok but was a nightmare to maintain. Moving that code to use a simple flexbox grid to manage the alignment greatly simplified the layout. The complexity of the CSS is greatly reduced and the page behavior is much more consistent across viewport sizes.

Big win!

Flexbox and min-width

Eeeeeh, hold on there doc – not so fast. After I pushed up the new layout I noticed that a number of posts with wide code blocks were breaking at various sizes. Which was odd because the code that controls code blocks using pre tags and overflow restraints has been there forever and has always worked.

The layout for the main blog content is responsive, so it resizes based on viewport width along with some media queries to redefine the layout at smaller sizes.  But after moving to Flexbox I noticed that all code snippets that were longer were causing the posts to cut off the right side of the content. This wasn't affecting just the actual code snippets, but ended up pushing the entire container content off the page.

Here's what this looked like:

PreOverflowProblem

The bar on the right is the browser scrollbar which shows the edge of the window and you can see that the content is pushing out beyond the window's boundaries. Notice that even though I have overflow-x: auto set on the <pre> block there are no scrollbars on the code block.

I've been using the following CSS:

pre
{    
    max-width: 100%;
    overflow-x: auto;
    background: #eee;    
}

Simple and obvious, right? Should just work. And it used to. Except it doesn't inside of a flex element.

Notice the overflow-x: auto which should and has in the past managed to handle the overflow for the <pre> tag properly. However after adding a Flexbox container in which the content is now rendered, the overflow on the PRE tag no longer works.

Flex Container Differences: min-width

It turns out there are a few CSS default values that Flexbox sets differently on Flexbox containers than standard block layout. The one specifically that affects my above layout is min-width which in Flexbox is set to auto instead of the value of 0 which is the block display default. min-width can affect how a container manages resizing itself when a flex element is set to flex (flex: 1 for example).

The default value for min-width in a flex element is auto, which is new value for min-width that is valid only inside of a flex element. Here's the info in the spec. To say this is a confusing and unexpected default value is an understatement.

In the example above max-width and min-width values are in conflict and it appears that min-width is winning out resulting in the pre tag overflowing (in an odd way actually – it overflows by a small amount not even to its full length because the scrollbars eventually kick in from the overflow-x setting).

In other words the behavior is a bit unexpected and min-width is the culprit.

To be clear the min-width value is not always a problem – in many cases you can get by with various overflow hidden/auto/scroll settings and the element that has the overflow will manage its sizing correctly. However, the pre tag in particular is tricky because of its special white-space: pre setting which causes content to automatically overflow unless you explicitly constrain it. It turns out that the container's min-width affects this behavior and hence the problem. You may see this with other elements that use overflow or overflow-x but in my testing it's much less of a problem with standard elements than it is with <pre>.

So how do we fix this?

The solution to this particular problem is to set min-width: 0 on the flex element, which in my case is the container that wraps my blog article content which in turn contains the <pre> tags. I can set the styling on the post content (either inline or via a CSS class).

Here's the simplified layout (with the relative inline styles to demonstrate):

<div class="post-container" style="display: flex">
    <aside class="post-sidebar" style="flex: none">
        ...
    </aside>

    <main class="post-content" style="flex: 1; min-width: 0">
       …
        <pre style="overflow: auto; max-width: 100%">

        </pre>
    </main>
</div>

The key element is:

<main class="post-content" style="min-width: 0">   

which is the flex child of the Flexbox container that manages the two vertical panes of content. Note it's not sufficient to slap the min-width: 0 on the errand <pre> tag – that has no effect. It has to be the flex element that receives the setting which is the post-content container in this case.

With that setting in place content now properly respects the overflow and margins and behaves the same as it did prior to using Flexbox containers:

propermargins

Global Fix

The above fix by slapping min-width: 0 on to the flex element works, but it's one of those things that's too easy to forget about and run into trouble with again later. While I ran into this problem with <pre> tags this problem can affect any content that has overflow restrictions because the overflow is controlled by the width of the container, and without explicitly setting min-width that width often can behave quite differently than you might expect.

This is annoying to say the least so in most cases I've now taken to overriding min-width as part of my Normalize CSS:

html, body, div, span,  object, iframe, table, caption, tbody, tfoot, thead, tr, th, td, 
del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, 
h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, 
dl, dt, dd, ol, ul, li, fieldset, form, label, legend, article, main, nav, ins {
    padding: 0;
    margin: 0;
    border: 0;
    outline: 0;        
    line-height: inherit;
    vertical-align: baseline;
    font-family: inherit;
    font-size: 100%;
    min-width: 0; 
}

And this works to set the min-width for local fix the problem as well. I'm not quite sure why Flexbox forces min-width to auto but I haven't seen any problems with min-width:0 in flex elements, so I think this is a relatively safe tweak to make.

Internet Explorer

On a side note, it appears that Internet Explorer doesn't set min-width value to some indeterminate value but explicitly uses 0, so I didn't see the funky wrapping behavior in IE initially. All other browsers I tested (Chrome, Safari, FireFox and Opera) however exhibit the same Flexbox behavior with an indeterminate min-width. One more reason to be explicit about setting the value globally perhaps.

Summary

Problems like this make me wish I was in a different line of work. It took me a while to track this nasty issue down.  Finding  a behavior problem in a pre tag that was actually controlled based on the behavior of the parent container which in turn is controlled by differing behavior of Flexbox is ridiculously difficult to debug and track down. It took about 20 different StackOverflow issues to correlate onto this particular problem which is not surprising given the causal relationship between the element in question and the container that caused the actual issue.

Hopefully this post will make this easier to figure out in the future. I just hope I'll remember I wrote this post when I run into this problem again which is likely given the default browser behavior.

Posted in CSS  HTML5  Flexbox  

The Voices of Reason


 

Ciaran O'Neill
February 16, 2016

# re: Flexbox Containers, PRE tags and managing Overflow

Thanks so much for this post Rick - you've just saved me a ton of investigation work. I had a similar issue appear 2 weeks ago after Chrome auto updated. In my case I have a screen with a kendo ui grid in the right part and I need the kendo grid to scroll horizontally, not the page or container div. It was displaying correctly in Chrome before the update. Applying min-width:0 solved my issue :)

Another thing to note for any flexbox users is that IE doesn't seem to recognise the same flexbox shorthand as other browsers. My grid is in a flexed div with
flex: 7 1 0
For IE to interpret this correctly the unit needs to be specified
flex: 7 1 0px

sojborg
February 16, 2016

# re: Flexbox Containers, PRE tags and managing Overflow

Wauw! I agree with you. Stuff like this makes you think that WPF or desktop application is not that bad after all.

But thanks for sharing!

RobJacobs
February 16, 2016

# re: Flexbox Containers, PRE tags and managing Overflow

I've found this resource to be very helpful when working with flexboxes: https://github.com/philipwalton/flexbugs/

Richard
February 16, 2016

# re: Flexbox Containers, PRE tags and managing Overflow


Lori
February 21, 2016

# re: Flexbox Containers, PRE tags and managing Overflow

Thank you so much for posting this solution! I just discovered the same problem on my website after migrating to flexbox.

cowgod
September 06, 2016

# re: Flexbox Containers, PRE tags and managing Overflow

This was extremely helpful. I just converted my blog to flexbox and has this exact issue, and now it's resolved! Thanks!

Max
September 12, 2016

# re: Flexbox Containers, PRE tags and managing Overflow

Thanks a million. Had exact same problem and didn't find a solution until stumbling into your splendid post.

Andrew
January 26, 2017

# re: Flexbox Containers, PRE tags and managing Overflow

I too needed this fix as an injected article layout was destroying my flex pages. Thanks for publicizing the technique.


Terry
August 28, 2018

# re: Flexbox Containers, PRE tags and managing Overflow

You're a lifesaver! Thanks for taking the time to document this.


Matt Keys
March 08, 2019

# re: Flexbox Containers, PRE tags and managing Overflow

Just writing to say thanks. Ran into this issue today and it would have taken me a long time to sort this one out without this post.


Anders Gustafson
March 01, 2020

# re: Flexbox Containers, PRE tags and managing Overflow

Many thanks Rick for documenting this issue. I ran into the same problem when starting to use Flexbox layout, and your solution seems to solve it.


James Meyer
May 09, 2020

# re: Flexbox Containers, PRE tags and managing Overflow

Thanks so much for this, it was driving me nuts. I am currently trying to update my rather dated site and I ran into this problem. If it's of any help to anyone with this problem, I also found that if the flex is in column direction, then you also have to set the width of the flex container to 100% or else the same breakout problem occurs.


Laurens
October 23, 2020

# re: Flexbox Containers, PRE tags and managing Overflow

Found your post through https://drailing.net/2018/04/css-quicky-fixing-flexbox-width-with-pre-tags/.

I stumbled upon the breakout problem of pre inside a parent which was itself part of a display: grid rendering using auto in grid-template-columns. Applying min-width: 0 to the parent solved the issue. So it seems the solution and underlying implementations relate to flexbox as well as to grid layouts - in Chrome at least.


Nick
July 30, 2024

# re: Flexbox Containers, PRE tags and managing Overflow

Checking in from 2024. This is still useful, solved my problem!


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024