HTML preprocessors can make writing HTML more powerful or convenient. For instance, Markdown is designed to be easier to write and read for text documents and you could write a loop in Pug.
In CodePen, whatever you write in the HTML editor is what goes within the <body>
tags in a basic HTML5 template. So you don't have access to higher-up elements like the <html>
tag. If you want to add classes there that can affect the whole document, this is the place to do it.
In CodePen, whatever you write in the HTML editor is what goes within the <body>
tags in a basic HTML5 template. If you need things in the <head>
of the document, put that code here.
The resource you are linking to is using the 'http' protocol, which may not work when the browser is using https.
CSS preprocessors help make authoring CSS easier. All of them offer things like variables and mixins to provide convenient abstractions.
It's a common practice to apply CSS to a page that styles elements such that they are consistent across all browsers. We offer two of the most popular choices: normalize.css and a reset. Or, choose Neither and nothing will be applied.
To get the best cross-browser support, it is a common practice to apply vendor prefixes to CSS properties and values that require them to work. For instance -webkit-
or -moz-
.
We offer two popular choices: Autoprefixer (which processes your CSS server-side) and -prefix-free (which applies prefixes via a script, client-side).
Any URLs added here will be added as <link>
s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.
You can apply CSS to your Pen from any stylesheet on the web. Just put a URL to it here and we'll apply it, in the order you have them, before the CSS in the Pen itself.
You can also link to another Pen here (use the .css
URL Extension) and we'll pull the CSS from that Pen and include it. If it's using a matching preprocessor, use the appropriate URL Extension and we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.
JavaScript preprocessors can help make authoring JavaScript easier and more convenient.
Babel includes JSX processing.
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.
You can apply a script from anywhere on the web to your Pen. Just put a URL to it here and we'll add it, in the order you have them, before the JavaScript in the Pen itself.
If the script you link to has the file extension of a preprocessor, we'll attempt to process it before applying.
You can also link to another Pen here, and we'll pull the JavaScript from that Pen and include it. If it's using a matching preprocessor, we'll combine the code before preprocessing, so you can use the linked Pen as a true dependency.
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.
Using packages here is powered by esm.sh, which makes packages from npm not only available on a CDN, but prepares them for native JavaScript ESM usage.
All packages are different, so refer to their docs for how they work.
If you're using React / ReactDOM, make sure to turn on Babel for the JSX processing.
If active, Pens will autosave every 30 seconds after being saved once.
If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.
If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.
Visit your global Editor Settings.
<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>
.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;
}
Also see: Tab Triggers