<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Evan Minto</title><description>Web &amp; game developer, designer, writer, animator, and musician</description><link>https://evanminto.com/</link><language>en-us</language><item><title>Responsive Floats Using the “Switcher Expression”</title><link>https://evanminto.com/blog/responsive-floats-using-switcher-expression</link><guid isPermaLink="true">https://evanminto.com/blog/responsive-floats-using-switcher-expression</guid><description>A way to display HTML elements as blocks in small containers and floats in larger containers.</description><pubDate>Mon, 14 Oct 2019 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Back in the day (...five or ten years ago), if you wanted to put two things next to each other in CSS, you needed to use floats. It was a hack, taking a feature meant for wrapping text around images and abusing it to create multi-column layouts. These days Flexbox and Grid have replaced the handy ol’ float for this purpose, so we can finally float only the things that &lt;em&gt;should&lt;/em&gt; be floated.&lt;/p&gt;
&lt;p&gt;Still, now that we’ve got these new tools, floats are starting to show their age. Flexbox and Grid have mechanisms for dynamically allocating space based on the container size (Flexbox is all about exactly this, and Grid has &lt;code&gt;auto-fill&lt;/code&gt;/&lt;code&gt;auto-fit&lt;/code&gt;), but floats just... float.&lt;/p&gt;
&lt;p&gt;What if I want an element to float in some circumstances but &lt;em&gt;not&lt;/em&gt; float in others? For example, when the container gets too small and the text is getting pushed out by the floated element, I’d like it to stop floating and just behave like a regular, un-floated block. Previously I would have used a media query to solve this, but doing so couples my float’s state to the &lt;em&gt;viewport&lt;/em&gt; size, meaning that I can’t use it in a reusable component. Another option is to set the float’s width to a percentage (say, 50% of the container width), but then we end up with a teensy tiny floated element when the container gets really small.&lt;/p&gt;
&lt;p&gt;What we really need is something like the &lt;a href=&quot;https://every-layout.dev/layouts/switcher/&quot;&gt;“Switcher” from Every Layout&lt;/a&gt;: a component that can &lt;strong&gt;switch between floated and un-floated versions based on the container size&lt;/strong&gt;. It turns out we can achieve just that by stealing a bit of code from that very same Switcher layout! Without further ado:&lt;/p&gt;
&lt;p&gt;&amp;lt;codepen-embed username=&quot;vamptvo&quot; pen=&quot;MWWKKJz&quot; name=&quot;Switcher Float&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.float {
  --breakpoint: 40rem;
  --min-size: 40%;
  --gap: 1.5rem;

  float: left;
  width: calc((var(--breakpoint) - 100%) * 9999);
  min-width: var(--min-size);
  max-width: 100%;
  margin-bottom: var(--gap);
  margin-right: var(--gap);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/codepen-embed&amp;gt;&lt;/p&gt;
&lt;p&gt;The element now floats to the left and takes up 40% of the container width. When the container width drops below &lt;code&gt;40rem&lt;/code&gt;, the floated element takes up 100% of the container width and pushes the surrounding text underneath it.&lt;/p&gt;
&lt;p&gt;So how does it work? Let’s break it down line by line.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;float: left;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Obviously we need to float the element, though notice that there’s no code here to “un-float” it. That’s because it’s going to stay floated regardless of the available space; we’re just going to make it &lt;em&gt;look&lt;/em&gt; like it’s set to &lt;code&gt;float: none;&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;width: calc((var(--breakpoint) - 100%) * 9999);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the key right here. It’s what I’ll henceforth refer to as the “switcher expression,” the &lt;code&gt;calc()&lt;/code&gt; expression that enables the Switcher layout. The &lt;code&gt;var(--breakpoint)&lt;/code&gt; is a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/--*&quot;&gt;custom property&lt;/a&gt;, CSS’s new-ish built-in variable feature. The rest of it is a fancy way of comparing that breakpoint value with the current width of the element, returning a huge positive number (if the width is smaller than the breakpoint), a huge negative number (if the width is larger than the breakpoint), or zero (if the widths are the same). For a more in-depth explanation of how it works, I recommend you &lt;a href=&quot;https://every-layout.dev/checkout/&quot;&gt;purchase the full version of Every Layout&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This line gets us most of the way there, but obviously we don’t want to actually use these huge numbers as-is. In the original Switcher layout, this value is used as the &lt;code&gt;flex-basis&lt;/code&gt;, and standard Flexbox behavior ensures that very large or small values get clamped. We don’t have that luxury here, so instead we need to use...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;min-width: var(--min-size);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When the value of the switcher expression results in a non-positive number, we want to clamp the value to some sensible minimum, in this case 40% of the container size. &lt;code&gt;min-width&lt;/code&gt; is perfect for the job. This value &lt;em&gt;must&lt;/em&gt; be a percentage, at least in most browsers (more on that in a bit), since a fixed length value would mean that the floated element would overflow its container when the container width is smaller than the minimum.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;max-width: 100%;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we handle the other side. When the switcher expression results in a huge positive number, we clamp it down to 100% of the container size. When the element fills its width, there’s no more space for text to wrap around it, so the text starts directly below it, as if it weren’t floated at all.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;margin-bottom: var(--gap);
margin-right: var(--gap);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, we add margins on the bottom and right side of the element, ensuring a readable gutter for text to flow around. You might be worried about putting a gutter on the right side when the element gets set to 100% width, but because it’s floated and sits outside of regular flow, this margin has no effect. Perfect!&lt;/p&gt;
&lt;h2&gt;Caveat: &lt;code&gt;min-width&lt;/code&gt; Must Be a Percentage&lt;/h2&gt;
&lt;p&gt;The biggest caveat is that &lt;code&gt;min-width&lt;/code&gt; has to be a percentage length. This can be slightly alleviated by using the &lt;code&gt;calc()&lt;/code&gt; expression I showcased in my post about &lt;a href=&quot;https://evanminto.com/blog/intrinsically-responsive-css-grid-minmax-min/&quot;&gt;intrinsically responsive CSS Grids&lt;/a&gt;: &lt;code&gt;calc(10% + 5rem)&lt;/code&gt;. This expression changes its value based on the container, but the container size has less influence than it would have on a pure percentage value. It does still have a fixed minimum size (meaning there’s a risk of overflow), but it’s much smaller than it would be if we just set a fixed minimum. Still, this approach is pretty finnicky. It can be hard to pick the right values to get a size you want.&lt;/p&gt;
&lt;p&gt;Thankfully, as I mentioned in the Grid post, Safari supports some new functions that can help us here.&lt;/p&gt;
&lt;p&gt;&amp;lt;codepen-embed username=&quot;vamptvo&quot; pen=&quot;ZEEQQJP&quot; name=&quot;Switcher Float with min()&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;--min-size: 20rem;
--switcher-width: calc((var(--breakpoint) - 100%) * 9999);

width: max(min(var(--min-size), 100%), min(var(--switcher-width), 100%));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/codepen-embed&amp;gt;&lt;/p&gt;
&lt;p&gt;Using the &lt;code&gt;min()&lt;/code&gt; and &lt;code&gt;max()&lt;/code&gt; functions, we can clamp the switcher value &lt;em&gt;and&lt;/em&gt; prevent overflow in small containers. The &lt;code&gt;min()&lt;/code&gt; functions prevent either the &lt;code&gt;--min-size&lt;/code&gt; or the &lt;code&gt;--switcher-width&lt;/code&gt; from exceeding the width of the container, ensuring that they are safe to use without any overflow. Then the &lt;code&gt;max()&lt;/code&gt; function selects the larger of the two values to use as the final computed width.&lt;/p&gt;
&lt;p&gt;Safari is the only browser that supports &lt;code&gt;min()&lt;/code&gt; and &lt;code&gt;max()&lt;/code&gt; right now (no support for &lt;code&gt;clamp()&lt;/code&gt; just yet), but Chrome is working on adding support.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;a-attention-box&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; I was tempted to use &lt;code&gt;min()&lt;/code&gt; inside the &lt;code&gt;min-width&lt;/code&gt; declaration, but doing so coupled with a custom property reference causes a crash in Safari when opening the Web Inspector. Careful!&lt;/p&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h2&gt;Caveat: Ignores Intrinsic Width of Floated Element&lt;/h2&gt;
&lt;p&gt;If the element is an image, it will always take up 40% or 100% of the container width, regardless of its intrinsic dimensions. This can pose some problems for small images in large containers, but as long as you’re using sensible image dimensions this shouldn’t cause any big issues. And if you’re floating container elements like &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s, there’s nothing at all to worry about.&lt;/p&gt;
&lt;h2&gt;Caveat: CSS Shapes Can Cause Unexpected Floating&lt;/h2&gt;
&lt;p&gt;Certain CSS Shapes will cause text to wrap even in the small-container case, since carving out the custom shape makes enough space for the words to start filling in the gaps. This may actually be desirable in specific cases, but it’s definitely something to keep in mind.&lt;/p&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;I recommend this for almost any situation that calls for a regular float: images, figures, sidebars, you name it. Floating the element using the switcher expression makes your component much more portable, and makes it possible to build complex nested floats, such as this floated sidebar with a floated image inside it (resize your window to see it in action):&lt;/p&gt;
&lt;p&gt;&amp;lt;codepen-embed username=&quot;vamptvo&quot; pen=&quot;JjjGYJe&quot; name=&quot;Nested Floats&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;article&amp;gt;
  &amp;lt;h1&amp;gt;Float On&amp;lt;/h1&amp;gt;

  &amp;lt;p&amp;gt;
    I backed my car into a cop car the other day&amp;lt;br /&amp;gt;
    Well, he just drove off, sometimes life&apos;s okay&amp;lt;br /&amp;gt;
    I ran my mouth off a bit too much, oh, what did I say?&amp;lt;br /&amp;gt;
    Well, you just laughed it off, it was all okay&amp;lt;br /&amp;gt;
  &amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;
    And we&apos;ll all float on, okay&amp;lt;br /&amp;gt;
    And we&apos;ll all float on, okay&amp;lt;br /&amp;gt;
    And we&apos;ll all float on, okay&amp;lt;br /&amp;gt;
    And we&apos;ll all float on anyway, well&amp;lt;br /&amp;gt;
  &amp;lt;/p&amp;gt;

  &amp;lt;aside class=&quot;sidebar float&quot;&amp;gt;
    &amp;lt;img src=&quot;//placehold.it/1200x1200&quot; class=&quot;float&quot; /&amp;gt;

    &amp;lt;h2&amp;gt;Modest Mouse&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;
      Modest Mouse is an American rock band formed in 1992 in Issaquah,
      Washington and currently based in Portland, Oregon. The founding members
      are lead singer/guitarist Isaac Brock, drummer Jeremiah Green, and bassist
      Eric Judy. Strongly influenced by Pavement, Pixies, XTC, and Talking
      Heads, the band rehearsed, rearranged, and recorded demos for almost two
      years before finally signing with small-town indie label K Records and
      releasing numerous singles.
    &amp;lt;/p&amp;gt;
  &amp;lt;/aside&amp;gt;

  &amp;lt;p&amp;gt;
    A fake Jamaican took every last dime with that scam&amp;lt;br /&amp;gt;
    It was worth it just to learn from sleight-of-hand&amp;lt;br /&amp;gt;
    Bad news comes, don&apos;t you worry even when it lands&amp;lt;br /&amp;gt;
    Good news will work it&apos;s way to all them plans&amp;lt;br /&amp;gt;
    We both got fired on exactly the same day&amp;lt;br /&amp;gt;
    Well, we&apos;ll float on, good news is on the way&amp;lt;br /&amp;gt;
  &amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;
    And we&apos;ll all float on, okay&amp;lt;br /&amp;gt;
    And we&apos;ll all float on, okay&amp;lt;br /&amp;gt;
    And we&apos;ll all float on, okay&amp;lt;br /&amp;gt;
    And we&apos;ll all float on, alright&amp;lt;br /&amp;gt;
  &amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;
    Already we&apos;ll all float on&amp;lt;br /&amp;gt;
    Now don&apos;t you worry, we&apos;ll all float on&amp;lt;br /&amp;gt;
    Alright, already we&apos;ll all float on&amp;lt;br /&amp;gt;
    Alright, don&apos;t worry, we&apos;ll all float on&amp;lt;br /&amp;gt;
  &amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;
    Alright, already and we&apos;ll all float on&amp;lt;br /&amp;gt;
    Alright, already we&apos;ll all float on&amp;lt;br /&amp;gt;
    Alright, don&apos;t worry even if things end up a bit too heavy&amp;lt;br /&amp;gt;
    We&apos;ll all float on, alright&amp;lt;br /&amp;gt;
  &amp;lt;/p&amp;gt;

  &amp;lt;p&amp;gt;
    Already we&apos;ll all float on&amp;lt;br /&amp;gt;
    Alright, already we&apos;ll all float on&amp;lt;br /&amp;gt;
    Okay, don&apos;t worry, we&apos;ll all float on&amp;lt;br /&amp;gt;
    Even if things get heavy, we&apos;ll all float on&amp;lt;br /&amp;gt;
    Alright, already we&apos;ll all float on&amp;lt;br /&amp;gt;
    Alright, no don&apos;t you worry, we&apos;ll all float on&amp;lt;br /&amp;gt;
    Alright, all float on&amp;lt;br /&amp;gt;
  &amp;lt;/p&amp;gt;
&amp;lt;/article&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;* {
  box-sizing: border-box;
  margin-bottom: 0;
  margin-top: 0;
}

/* Default vertical rhythm */
* + * {
  margin-top: 1.5rem;
}

br {
  margin: 0;
}

.float {
  --direction: left;
  --breakpoint: 40rem;
  --min-size: 33.333%;
  --gap: 1.5rem;

  /* 1 for right margin, 0 for left margin */
  --use-right-margin: 1;

  float: var(--direction);
  width: calc((var(--breakpoint) - 100%) * 9999);
  min-width: var(--min-size);
  max-width: 100%;
  margin-right: calc(var(--use-right-margin) * var(--gap));
  margin-left: calc((1 - var(--use-right-margin)) * var(--gap));
  margin-bottom: var(--gap);
}

/* Remove default top margin since the floated element is removed from flow. */
.float + * {
  margin-top: 0;
}

.sidebar {
  --direction: right;
  --use-right-margin: 0;

  background: tan;
  padding: 1.5rem;
}

.sidebar .float {
  --breakpoint: 25rem;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/codepen-embed&amp;gt;&lt;/p&gt;
&lt;p&gt;Or we can build an even more expressive collection of custom properties to allow consumers of this component to fine-tune the sizing of both the float and the text next to it. In this version, the &lt;code&gt;--breakpoint&lt;/code&gt; isn’t a fixed value; it’s computed by adding together the minimum size of the float, the gap, and the &lt;code&gt;--min-measure&lt;/code&gt;, a length using &lt;code&gt;ch&lt;/code&gt; units (each is equal to the width of the &lt;code&gt;0&lt;/code&gt; character in the current font). Now we don’t have to express the breakpoint as a fixed number. We can express it based on the minimum number of characters we want to see in the right-hand column before breaking to the stacked version of the layout.&lt;/p&gt;
&lt;p&gt;&amp;lt;codepen-embed username=&quot;vamptvo&quot; pen=&quot;eYYJRVV&quot; name=&quot;Switcher Float with min() and --min-measure&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.float {
  /* Add up the components that make up the total width: target float size, gap, and target measure. */
  --breakpoint: calc(var(--min-size) + var(--gap) + var(--min-measure));

  /* Minimum number of characters to show in a line of text next to the float before making the float fill the container. */
  --min-measure: 30ch;

  /* Minimum size of the float when it&apos;s actually floating. Set the fallback version to customize percentage behavior and set the advanced one to customize fixed width behavior. */
  --min-size: var(--min-size-fallback);
  --min-size-fallback: 33.333%;
  --min-size-advanced: 20rem;

  /* Gap between the float and its surrounding elements. */
  --gap: 1.5rem;

  /* Width of the float will change based on container size. */
  --switcher-width: calc((var(--breakpoint) - 100%) * 9999);

  float: left;
  width: var(--switcher-width);
  min-width: var(--min-size);
  max-width: 100%;
  margin-right: var(--gap);
  margin-bottom: var(--gap);
}

@supports (width: max(1rem, min(calc(2rem + 3rem), 4rem))) {
  .float {
    /* Set the minimum size to the advanced version, since it&apos;s supported. */
    --min-size: var(--min-size-advanced);

    width: max(min(var(--min-size), 100%), min(var(--switcher-width), 100%));

    /* Remove these constraints, since the max() and min() expression above handles them already. */
    min-width: 0;
    max-width: none;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/codepen-embed&amp;gt;&lt;/p&gt;
&lt;p&gt;And there you have it! Floats that respond to the container size. Another old-school CSS layout that we can transform into a modern, intrinsically responsive version.&lt;/p&gt;
</content:encoded></item><item><title>Intrinsically Responsive CSS Grid with minmax() and min()</title><link>https://evanminto.com/blog/intrinsically-responsive-css-grid-minmax-min</link><guid isPermaLink="true">https://evanminto.com/blog/intrinsically-responsive-css-grid-minmax-min</guid><description>A new technique using CSS math functions to make a grid that&apos;s responsive based on its container size, with no minimum width.</description><pubDate>Thu, 11 Jul 2019 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout&quot;&gt;CSS Grid&lt;/a&gt; is now widely supported across modern browsers, and there are lots of folks doing great work with it! But unfortunately, one of the most useful features of the specification doesn’t quite work as advertised. Specifically, it’s not possible to create an “intrinsically responsive grid” — that is, &lt;strong&gt;a grid that is responsive based on the size of its container, without the use of media queries&lt;/strong&gt;. But thanks to some standards that are now available in some browsers and on their way to others, we can fix that!&lt;/p&gt;
&lt;p&gt;Before I explain the solution, let’s review the problem. With CSS Grid, we can create a grid of items arranged in equally sized columns and tell those column sizes to adjust based on the amount of available space:&lt;/p&gt;
&lt;p&gt;&amp;lt;codepen-embed username=&quot;vamptvo&quot; pen=&quot;dBawwg&quot; name=&quot;Responsive Grid with Minimum Container Size&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ul {
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));

  list-style: none;
  padding: 0;
}

ul &amp;gt; * {
  background: black;
  height: 10rem;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/codepen-embed&amp;gt;&lt;/p&gt;
&lt;p&gt;This technique uses a number of features in the Grid specification:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;repeat()&lt;/code&gt; tells Grid to create multiple tracks with the same size parameters (not necessarily the same size, though in this case they all end up being the same).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;auto-fill&lt;/code&gt; tells it to create as many tracks as necessary to fill the space.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;minmax(10rem, 1fr)&lt;/code&gt; tells it to determine each track’s size by finding a value between a minium of &lt;code&gt;10rem&lt;/code&gt; and a maximum of &lt;code&gt;1fr&lt;/code&gt;. The &lt;code&gt;fr&lt;/code&gt; unit is what makes sure that the tracks are allowed to grow to fill any remaining space.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to all this, the container adds new columns as it grows. A key feature of this solution is that the columns change based on the &lt;em&gt;container&lt;/em&gt; size, not the viewport size. That means we can apply this to a reusable component and be confident that it will always look right, without the need for media queries overriding the default behavior on specific pages. So what’s the problem?&lt;/p&gt;
&lt;h2&gt;Responsive... Sorta&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Since each grid track has a &lt;em&gt;minimum&lt;/em&gt; size of &lt;code&gt;10rem&lt;/code&gt;, they can’t shrink below that size. That means when the container is smaller than &lt;code&gt;10rem&lt;/code&gt;, the grid items overflow the container! To fix this, we’d have to wrap the &lt;code&gt;grid-template-columns&lt;/code&gt; delcaration in a media query, like so:&lt;/p&gt;
&lt;p&gt;&amp;lt;codepen-embed username=&quot;vamptvo&quot; pen=&quot;qzvLar&quot; name=&quot;Responsive Grid with Media Query&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ul {
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: 1fr;

  list-style: none;
  padding: 0;
}

@media (min-width: 35.5em) {
  ul {
    grid-template-columns: repeat(auto-fill, minmax(min(10rem, 100%), 1fr));
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/codepen-embed&amp;gt;&lt;/p&gt;
&lt;p&gt;But now that we’re in media query-land, our grid only switches when the &lt;em&gt;viewport&lt;/em&gt; is small. We can’t put it inside a small &lt;em&gt;container&lt;/em&gt;, or we run into the overflow problem all over again. This is why &lt;a href=&quot;https://twitter.com/heydonworks&quot;&gt;Heydon Pickering&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/andybelldesign&quot;&gt;Andy Bell&lt;/a&gt;’s &lt;a href=&quot;https://every-layout.dev&quot;&gt;Every Layout&lt;/a&gt; site generally avoids media queries and CSS Grid, instead achieving intrinsic responsiveness through Flexbox.&lt;/p&gt;
&lt;p&gt;Thankfully, with some new additions to the CSS spec that have started landing in browsers, we can fix this issue, allowing CSS Grid to live up to its full potential as a tool for &lt;a href=&quot;http://www.zeldman.com/2018/05/02/transcript-intrinsic-web-design-with-jen-simmons-the-big-web-show/&quot;&gt;intrinsic web design&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The Intrinsically Responsive Grid&lt;/h2&gt;
&lt;p&gt;The previous example ran into problems because we were setting a fixed value as the minimum track size. When the container size shrunk, the items didn’t shrink with it, and thus: overflow. But what if we could set a minimum size that would shrink based on the container size, ensuring that our tracks were never too big for their container?&lt;/p&gt;
&lt;p&gt;As luck would have it, we can do just that, with the help of the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/min&quot;&gt;&lt;code&gt;min()&lt;/code&gt; function&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;grid-template-columns: repeat(auto-fill, minmax(min(10rem, 100%), 1fr));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;min()&lt;/code&gt; accepts one or more values and returns the smallest value. The magic of the function is that, just like &lt;code&gt;calc()&lt;/code&gt;, the arguments can use different units, which allows us to return values that change dynamically based on context. In this case, we’re returning the current width of the container, capped at a maximum value of &lt;code&gt;10rem&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;min()&lt;/code&gt; is one of three new comparison functions introduced as part of the &lt;a href=&quot;https://drafts.csswg.org/css-values-4/#comp-func&quot;&gt;CSS Values and Units Module Level 4&lt;/a&gt;. There’s also &lt;code&gt;max()&lt;/code&gt;, which naturally does the inverse of &lt;code&gt;min()&lt;/code&gt;. Finally &lt;code&gt;clamp()&lt;/code&gt; is a convenience function that applies both a minimum &lt;em&gt;and&lt;/em&gt; a maximum to a single value.&lt;/p&gt;
&lt;p&gt;In this example, there are two cases we have to worry about, and &lt;code&gt;min()&lt;/code&gt; solves for both of them. When the container is &lt;em&gt;smaller&lt;/em&gt; than &lt;code&gt;10rem&lt;/code&gt;, the minimum value in our &lt;code&gt;minmax()&lt;/code&gt; expression is set to the full width of the container, giving us a nice single-column view with no overflow. When the container is &lt;em&gt;larger&lt;/em&gt; than &lt;code&gt;10rem&lt;/code&gt;, the minimum value is set to &lt;code&gt;10rem&lt;/code&gt;, so we get a responsive grid with equal tracks of at least &lt;code&gt;10rem&lt;/code&gt; each.&lt;/p&gt;
&lt;h2&gt;In the Real World&lt;/h2&gt;
&lt;p&gt;I know what you’re thinking. “This sounds cool and all, but I can’t actually &lt;em&gt;use&lt;/em&gt; it yet.” You’re only half right.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;min()&lt;/code&gt; isn’t very well supported, but it &lt;em&gt;is&lt;/em&gt; available in at least one browser: Safari quietly implemented both &lt;code&gt;min()&lt;/code&gt; and &lt;code&gt;max()&lt;/code&gt; a few versions back! Unfortunately there’s no &lt;code&gt;clamp()&lt;/code&gt; yet, but you can simulate it using the other two. Plus, Tab Atkins recently announced that &lt;a href=&quot;https://twitter.com/tabatkins/status/1141830941628780544&quot;&gt;Chrome support is on its way&lt;/a&gt;. If you want to keep track of browser support, &lt;a href=&quot;https://caniuse.com/#feat=css-math-functions&quot;&gt;CanIUse has a page for all three functions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With that good news out of the way, here’s a working version of the code above (open in Safari to see it in action):&lt;/p&gt;
&lt;p&gt;&amp;lt;codepen-embed username=&quot;vamptvo&quot; pen=&quot;VJggRL&quot; name=&quot;Fully Responsive Grid (Safari-Only)&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ul {
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(10rem, 100%), 1fr));

  list-style: none;
  padding: 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/codepen-embed&amp;gt;&lt;/p&gt;
&lt;p&gt;One browser isn’t great, but it doesn’t mean you have to give up on this solution. For now, you can layer it onto your existing code as a progressive enhancement. Here’s my preferred solution:&lt;/p&gt;
&lt;p&gt;&amp;lt;codepen-embed username=&quot;vamptvo&quot; pen=&quot;bPzzZr&quot; name=&quot;Fully Responsive Grid (with Fallback)&quot;&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ul {
  display: grid;
  grid-gap: 1rem;

  /* Partially responsive fallback */
  grid-template-columns: repeat(auto-fill, minmax(calc(10% + 7.5rem), 1fr));

  /* Fully responsive version */
  grid-template-columns: repeat(auto-fill, minmax(min(10rem, 100%), 1fr));

  list-style: none;
  padding: 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/codepen-embed&amp;gt;&lt;/p&gt;
&lt;p&gt;This one uses a &lt;code&gt;calc()&lt;/code&gt; expression as a fallback. The key part is the &lt;code&gt;calc(10% + 7.5rem)&lt;/code&gt;, which combines a fixed minimum with a percentage width. By computing the minimum based on &lt;em&gt;both&lt;/em&gt; of these, we lower the threshold for triggering overflow. Now it will trigger when the container is slightly larger than &lt;code&gt;7.5rem&lt;/code&gt;, whereas in our earlier solution it would trigger at &lt;code&gt;10rem&lt;/code&gt;. This solution is a bit finnicky though, so you’ll want to adjust both the percentage and fixed values to fit your grid’s design.&lt;/p&gt;
&lt;p&gt;With this as our fallback, we can take advantage of CSS’s ability to override duplicate property declarations by re-declaring &lt;code&gt;grid-template-columns&lt;/code&gt;. Browsers that support &lt;code&gt;min()&lt;/code&gt;, namely Safari, will get the fully responsive solution, while Chrome, Firefox, Edge, and others will get the fallback. As more browsers add support for &lt;code&gt;min()&lt;/code&gt;, they will automatically switch over to the new layout.&lt;/p&gt;
&lt;h2&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;min()&lt;/code&gt;, &lt;code&gt;max()&lt;/code&gt;, and &lt;code&gt;clamp()&lt;/code&gt; functions are really powerful tools, allowing us to toggle between values in real time based on changing conditions. Being able to test them out in a real browser opens up lots of opportunities for exploration, and I’m confident that this little fix for CSS Grid is just scratching the surface of the many ways that developers will use these features going forward.&lt;/p&gt;
</content:encoded></item><item><title>Cutting the Ribbon on My Personal Blog</title><link>https://evanminto.com/blog/cutting-the-ribbon-on-my-personal-blog</link><guid isPermaLink="true">https://evanminto.com/blog/cutting-the-ribbon-on-my-personal-blog</guid><description>Introducing my new personal blog, which will feature mostly tech writing with the occasional pop culture post.</description><pubDate>Tue, 09 Jul 2019 07:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hello and welcome to the very first blog post on my personal site!&lt;/p&gt;
&lt;p&gt;Most of my writing covers Japanese animation, comics, video games, and related pop culture, and appears in pop culture outlets like &lt;a href=&quot;https://anigamers.com&quot;&gt;Ani-Gamers&lt;/a&gt;, &lt;a href=&quot;https://otakuusamagazine.com&quot;&gt;Otaku USA Magazine&lt;/a&gt;, and &lt;a href=&quot;https://animenewsnetwork.com&quot;&gt;Anime News Network&lt;/a&gt;. On very rare occasions, however, I actually write about the other half of my job: web design and development.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/@vamptvo/pixels-vs-ems-users-do-change-font-size-5cfb20831773&quot;&gt;My first post on the subject&lt;/a&gt; was published on Medium, but considering Medium‘s accessibility and usability problems, I’d like to host my future web dev writing somewhere I can guarantee will be a little more responsible. And for that, there’s nothing quite like a personal website.&lt;/p&gt;
&lt;p&gt;So this blog will be my repository for any web dev writing that I produce during the course of my freelance work. I’ll still keep most — if not all — of my anime writing in other outlets, but who knows, I may occasionally drop in here with some pop culture thoughts that don’t fit in anywhere else.&lt;/p&gt;
</content:encoded></item></channel></rss>