Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <main class="main-content">

  <h1>Flexbox-fu 🥋</h1>

  <div class="example">
    <h2>1) Default widths of container and item</h2>
    <ul class="example__container example__container--outlined">
      <li>item</li>
    </ul>
    <details>
      <summary>Tell me more</summary>
      <p>A flex <b>container</b> (dotted box) is full-width by default, regardless of flex-direction. That’s because <code>display:flex</code> is shorthand for <code>display:block flex</code> meaning “block on the outside, flexbox on the inside”. No need to set <code>width:100%</code>, just like you wouldn’t do that to a paragraph.</p>
      <p>A flex <b>item</b> (whose container’s <code>flex-direction</code> is <code>row</code>) is <em>not</em> full-width by default. Its default settings (shorthand <code>flex:initial</code>) are <code>flex-grow:0</code>, <code>flex-shrink:1</code>, <code>flex-basis:auto</code>, so:</p>
      <ol>
        <li>the <code>flex-basis:auto</code> evaluates to the item’s intrinsic width (<code>max-content</code>) unless a width has been explicitly set; and</li>
        <li><code>flex-grow:0</code> says “grow from your <code>flex-basis</code> into 0% of the available space” (so don’t grow at all).</li>
      </ol>
    </details>
  </div>

  <div class="example">
    <h2>2) Default width and behaviour of Flex Item when it is an inline element</h2>
    <div class="example__container example__container--outlined">
      <a href="/" style="outline: 1px solid firebrick;padding: 0.5rem;flex-basis: 30rem; margin-left: auto;">I’m an anchor with outline, padding, margin and flex-basis</a>
    </div>
    <details>
      <summary>Tell me more</summary>
      <div>
        <p>Any item within a flex container is automatically set to <code>display:block</code>. This includes inline elements such as the anchor and span elements!</p>
        <p>The flex rules (grow, shrink, basis, <code>auto</code> margins etc) take effect on the item regardless of whether the element is inline, block, list-item etc.</p>
      </div>
    </details>
  </div>

  <div class="example">
    <h2>3) Widths of container and item when flex-direction is column</h2>
    <ul class="example__container example__container--column example__container--outlined">
      <li>item</li>
    </ul>
    <details>
      <summary>Tell me more</summary>
      <div>
        <p>Again, the flex <b>container</b> is full width.</p>
        <p>(Note: it’s tempting to assume that a flex container in column-direction would be 100% <em>height</em> (of parent). This is not the case. Again, remember the container is “<code>block</code> on the outside” so its outer layout behaviour is no different from any other block-level element.)</p>
        <p>Here, the flex <strong>item</strong> is full-width by default (unlike in <code>flex-direction:row</code> contexts).</p>
        <p>This is because the row axis is now the <em>cross-axis</em>, and a flex container’s default <code>align-items</code> setting of <code>stretch</code> sets its items to fill the available space in the cross-axis.</p>
        <p>NB that default <code>align-items:stretch</code> setting is also what keeps items in a <code>row</code> container <em>equal-height</em>.</p>
      </div>
    </details>
  </div>

  <div class="example">
    <h2>4) Widths of container and item when display is inline-flex</h2>
    <ul class="example__container example__container--inline example__container--outlined">
      <li>item</li>
    </ul>
    <details>
      <summary>Tell me more</summary>
      <div>
        <p>The <b>container</b> is no longer full parent-width. It is now <code>inline flex</code> so it is “inline on the outside, flexbox on the inside”.</p>
        <p>The <b>item</b> behaves like a normal flex item.</p>
        <p>Use this when you want the container to be an inline element, for example so that its width is based on its intrinsic content.</p>
      </div>
    </details>
  </div>

  <div class="example">
    <h2>5) Let item grow wider than its intrinsic content</h2>
    <div class="example__container example__container--centred">
      <div class="example__can-grow">
        I’m programmed to grow (in this case up to an explicit max-width)
      </div>
    </div>

    <details>
      <summary>Tell me more</summary>
      <div>
        <p>To achieve this, set the flex item to: <code>flex:1</code>.</p>
        <p>By setting a flex item’s <code>flex-grow</code> property to 1 or greater we allow it to grow beyond its <code>flex-basis</code> into the available space. In the case of a single item it will take up all available space unless you limit it with a <code>max-width</code>.</p>
        <p> It’s recommended to use the shorthand <code>flex:1</code> which is short for <code>flex: 1 1 0</code>.</p>
        <p>Note that I’ve set this flex container to centre its item(s) via <code>justify-content: center;</code> but that’s just an arbitrary decision.</p>
        <p>(While this example illustrates the flexbox “grow” behaviour well, bear in mind that for a simple standalone element such as a horizontally centred column that doesn’t need to be vertically centred or have any other fancy behaviour or layout interrelationships, you don’t need flexbox at all. Just a block element, with a <code>max-width</code> and <code>margin: 0 auto;</code> would suffice).</p>
      </div>
    </details>
  </div>

  <div class="example example--menu-one">
    <h2>6) Full-width menu, equal-width items</h2>
    <ul class="example__container">
      <li>One</li>
      <li>Two Two</li>
      <li>Three Three Three</li>
      <li>Four Four Four Four</li>
    </ul>
    <details>
      <summary>Tell me more</summary>
      <div>
        <p>This is perhaps a more practical application of the Example 5 code above. Again, we simply set all flex items to: <code>flex:1</code>.</p>
        <p><code>flex:1</code> is short for <code>flex: 1 1 0</code>.</p>
        <p>This means that items i) all have an <strong>equal</strong> basis (0); ii) can all grow, so in combination they fill the container’s available space; and iii) all grow into an equal proportion of available space (because all have the same <code>flex-grow</code> value).</p>
        <p>Note: when using Flexbox to attempt to make items equal-width it’s worth considering that unless the items are simple, similar and have predictable inner content then the width equality might break. One alternative option might be to <a href="https://css-tricks.com/equal-columns-with-flexbox-its-more-complicated-than-you-might-think/#why-css-grid-is-the-better-choice-here">use CSS Grid instead</a> (or <em>in addition</em> as a progressive enhancement). However things get more complicated again when you need to consider responsive behaviour and whether i) using a media query; and ii) having an orphan item after wrapping… are acceptable compromises for your use case. The requirement to have equal width items is generally something for which Flexbox is perhaps not the ideal tool however when there are only two or three items I often reach for <a href="https://every-layout.dev/layouts/switcher/">Every Layout’s Switcher</a> because it ticks the most boxes, including intrinsic responsiveness and no orphan items.
      </div>
    </details>
  </div>

  <div class="example example--menu-two">
    <h2>7) Full-width menu, inequal-width items</h2>
    <ul class="example__container">
      <li>One</li>
      <li>Two Two</li>
      <li>Three Three Three</li>
      <li>Four Four Four Four</li>
    </ul>
    <details>
      <summary>Tell me more</summary>
      <div>
        <p>Set items to <code>flex:auto</code> (short for <code>flex: 1 1 auto</code>).</p>
        <p>This results in a full-width menu, but with inequal item widths. It’s because items i) have an <strong>inequal</strong> basis (<code>auto</code>, evaluating to their intrinsic widths, which are different); ii) can all grow, so together they fill the container’s available space; and iii) add an equal proportion of available space (<code>1</code>) onto their inequal starting basis so remain inequal.</p>
      </div>
    </details>
  </div>

  <div class="example example--menu-four">
    <h2>8) Non full-width menu, equal fixed-width items</h2>
    <ul class="example__container">
      <li>One</li>
      <li>Two Two</li>
      <li>Three Three Three</li>
    </ul>
    <details>
      <summary>Tell me more</summary>
      <div>
        <p>Here we just set an equal, unit-based, non-zero <code>flex-basis</code> on all items (e.g. 15ch). We opt to not allow them to grow, via <code>flex-grow:0</code>.</p>
        <p>If we want we can centre this with <code>justify-content:center</code>.</p>
      </div>
    </details>
  </div>

  <div class="example example--ellipsis">
    <h2>9) Shrink flex item to nothing or ellipsis</h2>
    <div class="example-container filename">
      <span class="filename__base">this-file-has-a-really-really-really-really-really-really-really-really-really-really-long-filename.</span><span class="filename__extension">pdf</span>
    </div>

    <details>
      <summary>Tell me more</summary>
      <div>
        <p>Here we set the second flex item (the file extension) to not shrink. We leave the first flex item’s flex-shrink property alone, so the item is able to shrink, by default. We set the flex-container’s <code>min-width</code> to 0, which – in combination with the first flex child having <code>white-space:nowrap</code> and <code>overflow:hidden</code> – allows that first flex child to shrink to less than the container’s and item’s standard <code>auto</code> width/basis so essentially shrinks to nothing.</p>
        <p>NB the text-overflow CSS property sets how hidden overflow content is signaled to users – in this case an ellipsis (…).</p>
      </div>
    </details>

  </div>

  <!-- 
  Horizontal Centring 
  <p>This example highlights that flexbox is not just for laying out multiple children. Often it can be useful to wrap even a single element in a flex container just to give it the benefits of being a flex child.</p>
  -->

  <!-- <div class="example">
    <h2>5) Setting a specific flex-basis</h2>
    <ul class="example__container menu-three">
      <li>Oh</li>
      <li>Oh</li>
      <li>Oh</li>
      <li>Oh</li>
    </ul>
  </div> -->

  <!-- <section class="docs">
    <h3>Notes:</h3>
    <ul class="docs-list">
      <li>A flex <b>container</b> is full-width by default, regardless of flex-direction. Applying <code>width:100%</code> is redundant. (Key takeaway: <code>display: flex</code> is shorthand for <code>display: block flex</code> meaning “block on the outside, flex on the inside”.</li>
    <li>It’s tempting to think that because a flex container has a width of <code>100%</code> then if we change its <code>flex-direction</code> to <code>column</code> it’d have a <code>height</code> of <code>100%</code>. This is not the case. Again, remember it is “<code>block</code> on the outside” so the container simply behaves like any block-level element.</li>
    <li>A flex <b>item</b> (inside a container with the default <code>flex-direction: row</code>) is <em>not</em> full-width by default. Its default <code>flex</code> value is: <code>0 1 auto</code> (<code>flex-grow: 0</code>, <code>flex-shrink: 1</code>, <code>flex-basis: auto</code>) so: 
      <ol>
        <li><code>flex-basis</code> evaluates to either its explicitly-set <code>width</code> (if present) or its intrinsic width; and</li>
        <li><code>flex-grow:0</code> says “grow into 0% (none) of the available space from your <code>flex-basis</code>”.</li>
      </ol>
    </li>
    <li>In a container with <code>flex-direction: column</code>, flex items <em>are</em> full-width by default! This is because the container’s default <code>align-items</code> setting is <code>stretch</code>, so they fill the available space in the cross-axis.</li>
    <li>Setting a flex item’s <code>flex-grow</code> property to 1 or greater allows it to grow beyond its basis into the available space. In the case of a single item it will take up all available space unless you limit it with a <code>max-width</code>. It’s recommended to use shorthand so in Example 4 we use <code>flex:1</code> (short for <code>flex: 1 1 0px</code>). This is useful for “full width on narrow viewports, fixed-width and centred on wider viewports”).</li>
     <li>Example 4 shows that flexbox is not just for laying out mutliple children. Often even when dealing with just a single element, it can be useful to wrap it in a flex container just to give it the benefits of being a flex child.</li>
    <li>In Example 5’s menu we set all flex items to: <code>flex:1</code>. This results in a full-width menu, and item widths being equal. It’s because they i) all have an <strong>equal</strong> basis (0); ii) can all grow, so together they fill the container’s available space; and iii) all grow into an equal proportion (1) of available space.</li>
    <li>In Example 6’s menu we set items to <code>flex:auto</code> (short for <code>flex: 1 1 auto</code>). This results in a full-width menu, but with inequal item widths. It’s because items i) have an <strong>inequal</strong> basis (their intrinsic widths, which are different); ii) can all grow, so together they fill the container’s available space; and iii) add an equal proportion of available space (1) onto their inequal starting basis so remain inequal.</li>
    <li>*Note 1: any single-digit value for <code>flex</code> not only sets <code>flex-grow</code> but also sets <code>flex-shrink:1</code> and <code>flex-basis:0px</code>. Just be aware of this. There may be times (for example when you’re using <code>flex-wrap:wrap</code> when you don’t want your item to be able to shrink down to 0. You may instead want them to have a positive <code>flex-basis</code> value, to act like a min-width.</li>
    <li>*Note 2: allowing <code>shrink</code> avoids overflow.</li>
    <li>The best docs I’ve found are <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox">MDN</a> and <a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/">CSS-tricks</a>.</li>
  </ul>
  </section> -->

</main>
              
            
!

CSS

              
                .example__container {
  display: flex;
}

.example__container--inline {
  display: inline-flex;
}

.example__container--column {
  flex-direction: column;
}

.example__container--centred {
  justify-content: center;
}

.example__can-grow {
  flex: 1;
  /* ^ when there’s only one item, `flex:auto` would have same effect since it also sets flex-grow=1, however when the intent is “grow”, flex:1 feels more explicit. */
  max-width: 525px;
}

.example--menu-one li {
  flex: 1;
  /* same as flex: 1 1 0px */
}

.example--menu-two li {
  flex: auto;
  /* same as flex: 1 1 auto */
}

.example--menu-three li {
  flex: 1 1 4ch;
}

/*.example--menu-four ul {
  justify-content: center;
}*/

.example--menu-four li {
  flex: 0 1 15ch;
}

/* Ellipsis example */

.filename {
  display: flex;
  min-width: 0;
}

.filename__base {
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

.filename__extension {
  flex-shrink: 0;
}

/* non-important additional styles */

body {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif,
    "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  font-size: 100%;
  line-height: 1.4;
  margin: 0 auto;
  max-width: 50em;
  padding: 1rem 1rem 10rem;
}

input,
textarea,
select,
button {
  font: inherit;
}

.main-content {
  max-width: 70ch;
  margin: 0 auto;
}

ul {
  margin-bottom: 1.5rem;
}

li ol {
  margin-top: 1rem;
}

.example + .example {
  margin-top: 4rem;
}

.docs {
  margin-top: 3rem;
}

.docs-list {
  margin-top: 1rem;
}

.docs-list li + li {
  margin-top: 1rem;
}

h2 {
  margin-top: 0;
  font-size: 1.2rem;
}

.example__container--outlined {
  outline: 1px #ccc dashed;
  padding: 1rem;
}

.example__can-grow {
  background: firebrick;
  color: #fff;
  padding: 0.5rem;
}

ul {
  margin: 0;
  padding: 0;
}

.example__container li {
  background: firebrick;
  color: #fff;
  text-align: center;
  padding: 0.5rem;
  list-style: none;
  margin: 0;
}

.example--menu-one li + li,
.example--menu-two li + li,
.example--menu-three li + li,
.example--menu-four li + li {
  margin-left: 0.5rem;
}

details {
  margin-top: 1rem;
  max-width: 65ch;
}

details p,
details ol {
  margin: 0.5rem 0 0;
}

              
            
!

JS

              
                
              
            
!
999px

Console