min()
operate, exploring its flexibility with totally different models to find out if it’s the be-all, end-all for responsiveness. Uncover the cautions he highlights in opposition to dogmatic approaches to internet design based mostly on his findings.
Did you see this publish that Chris Coyier printed again in August? He experimented with CSS container question models, going all in and utilizing them for each single numeric worth in a demo he put collectively. And the outcome was… not too unhealthy, really.
See the Pen [Container Units for All Units [forked]](https://codepen.io/smashingmag/pen/ExqWXOQ) by Chris Coyier.
What I discovered attention-grabbing about that is the way it demonstrates the complexity of sizing issues. We’re constrained to absolute and relative models in CSS, so we’re both caught at a selected measurement (e.g., px
) or computing the scale based mostly on sizing declared on one other ingredient (e.g., %
, em
, rem
, vw
, vh
, and so forth). Each include compromises, so it’s not like there’s a “appropriate” option to go about issues — it’s concerning the ingredient’s context — and leaning closely in anyone path doesn’t treatment that.
I assumed I’d strive my very own experiment however with the CSS min()
operate as an alternative of container question models. Why? Nicely, first off, we are able to provide the operate with any kind of size unit we would like, which makes the method somewhat extra versatile than working with one kind of unit. However the actual cause I needed to do that is private curiosity greater than the rest.
The Demo
I gained’t make you look ahead to the top to see how my min()
experiment went:
Taking web site responsiveness to a complete new stage 🌐 pic.twitter.com/pKmHl5d0Dy
— Vayo (@vayospot) March 1, 2023
We’ll speak about that extra after we stroll via the small print.
A Little About min()
The min()
operate takes two values and applies the smallest one, whichever one occurs to be within the ingredient’s context. For instance, we are able to say we would like a component to be as huge as 50%
of no matter container it’s in. And if 50%
is higher than, say 200px
, cap the width there as an alternative.
See the Pen [[forked]](https://codepen.io/smashingmag/pen/LYwWLMg) by Geoff Graham.
So, min()
is kind of like container question models within the sense that it’s conscious of how a lot out there area it has in its container. However it’s totally different in that min()
isn’t querying its container dimensions to compute the ultimate worth. We provide it with two acceptable lengths, and it determines which is finest given the context. That makes min()
(and max()
for that matter) a useful gizmo for responsive layouts that adapt to the viewport’s measurement. It makes use of conditional logic to find out the “finest” match, which suggests it may well assist adapt layouts while not having to succeed in for CSS media queries.
.ingredient {
width: min(200px, 50%);
}
/* Near this: */
.ingredient {
width: 200px;
@media (min-width: 600px) {
width: 50%;
}
}
The distinction between min()
and @media
in that instance is that we’re telling the browser to set the ingredient’s width to 50%
at a selected breakpoint of 600px
. With min()
, it switches issues up routinely as the quantity of obtainable area modifications, no matter viewport measurement that occurs to be.
Once I use the min()
, I consider it as being able to make sensible selections based mostly on context. We don’t need to do the pondering or calculations to find out which worth is used. Nevertheless, utilizing min()
coupled with simply any CSS unit isn’t sufficient. As an example, relative models work higher for responsiveness than absolute models. You may even consider min()
as setting a most worth in that it by no means goes beneath the primary worth but additionally caps itself on the second worth.
I discussed earlier that we may use any kind of unit in min()
. Let’s take the identical method that Chris did and lean closely into a sort of unit to see how min()
behaves when it’s used completely for a responsive structure. Particularly, we’ll use viewport models as they’re immediately relative to the scale of the viewport.
Now, there are totally different flavors of viewport models. We are able to use the viewport’s width (vw
) and peak (vh
). We even have the vmin
and vmax
models which can be barely extra clever in that they consider a component’s width and peak and apply both the smaller (vmin
) or bigger (vmax
) of the 2. So, if we declare 100vmax
on a component, and that ingredient is 500px
huge by 250px
tall, the unit computes to 500px
.
That’s how I’m approaching this experiment. What occurs if we eschew media queries in favor of solely utilizing min()
to ascertain a responsive structure and lean into viewport models to make it occur? We’ll take it one piece at a time.
Font Sizing
There are numerous approaches for responsive kind. Media queries are shortly turning into the “old fashioned” method of doing it:
p { font-size: 1.1rem; }
@media (min-width: 1200px) {
p { font-size: 1.2rem; }
}
@media (max-width: 350px) {
p { font-size: 0.9rem; }
}
Certain, this works, however what occurs when the person makes use of a 4K monitor? Or a foldable telephone? There are different tried and true approaches; in truth, clamp()
is the prevailing go-to. However we’re leaning all-in on min()
. Because it occurs, only one line of code is all we have to wipe out all of these media queries, considerably lowering our code:
p { font-size: min(6vmin, calc(1rem + 0.23vmax)); }
I’ll stroll you thru these values…
6vmin
is basically 6% of the browser’s width or peak, whichever is smallest. This enables the font measurement to shrink as a lot as wanted for smaller contexts.- For
calc(1rem + 0.23vmax)
,1rem
is the bottom font measurement, and0.23vmax
is a tiny fraction of the viewport‘s width or peak, whichever occurs to be the most important. - The
calc()
operate provides these two values collectively. Since0.23vmax
is evaluated in another way relying on which viewport edge is the most important, it’s essential in relation to scaling the font measurement between the 2 arguments. I’ve tweaked it into one thing that scales step by step come what may slightly than blowing issues up because the viewport measurement will increase. - Lastly, the
min()
returns the smallest worth appropriate for the font measurement of the present display measurement.
And talking of how versatile the min()
method is, it may well limit how far the textual content grows. For instance, we are able to cap this at a most font-size
equal to 2rem
as a 3rd operate parameter:
p { font-size: min(6vmin, calc(1rem + 0.23vmax), 2rem); }
This isn’t a silver bullet tactic. I’d say it’s most likely finest used for physique textual content, like paragraphs. We’d wish to alter issues a smidge for headings, e.g., <h1>
:
h1 { font-size: min(7.5vmin, calc(2rem + 1.2vmax)); }
We’ve bumped up the minimal measurement from 6vmin
to 7.5vmin
in order that it stays bigger than the physique textual content at any viewport measurement. Additionally, within the calc()
, the bottom measurement is now 2rem
, which is smaller than the default UA kinds for <h1>
. We’re utilizing 1.2vmax
because the multiplier this time, which means it grows greater than the physique textual content, which is multiplied by a smaller worth, .023vmax
.
This works for me. You’ll be able to at all times tweak these values and see which works finest to your use. Regardless of the case, the font-size
for this experiment is totally fluid and utterly based mostly on the min()
operate, adhering to my self-imposed constraint.
Margin And Padding
Spacing is an enormous a part of structure, responsive or not. We’d like margin
and padding
to correctly situate parts alongside different parts and provides them respiration room, each inside and outdoors their field.
We’re going all-in with min()
for this, too. We may use absolute models, like pixels, however these aren’t precisely responsive.
min()
can mix relative and absolute models so they’re simpler. Let’s pair vmin
with px
this time:
div { margin: min(10vmin, 30px); }
10vmin
is prone to be smaller than 30px
when seen on a small viewport. That’s why I’m permitting the margin to shrink dynamically this time round. Because the viewport measurement will increase, whereby 10vmin
exceeds 30px
, min()
caps the worth at 30px
, going no larger than that.
Discover, too, that I didn’t attain for calc()
this time. Margins don’t actually need to develop indefinitely with display measurement, as an excessive amount of spacing between containers or parts usually appears awkward on bigger screens. This idea additionally works extraordinarily nicely for padding, however we don’t need to go there. As a substitute, it is perhaps higher to stay with a single unit, ideally em
, since it’s relative to the ingredient’s font-size
. We are able to basically “go” the work that min()
is doing on the font-size
to the margin
and padding
properties due to that.
.card-info {
font-size: min(6vmin, calc(1rem + 0.12vmax));
padding: 1.2em;
}
Now, padding scales with the font-size
, which is powered by min()
.
Widths
Setting width
for a responsive design doesn’t need to be sophisticated, proper? We may merely use a single share or viewport unit worth to specify how a lot out there horizontal area we wish to take up, and the ingredient will alter accordingly. Although, container question models could possibly be a contented path exterior of this experiment.
However we’re min()
all the best way!
min()
is useful when setting constraints on how a lot a component responds to modifications. We are able to set an higher restrict of 650px
and, if the computed width tries to go bigger, have the ingredient settle at a full width of 100%
:
.container { width: min(100%, 650px); }
Issues get attention-grabbing with textual content width. When the width of a textual content field is simply too lengthy, it turns into uncomfortable to learn via the texts. There are competing theories about what number of characters per line of textual content is finest for an optimum studying expertise. For the sake of argument, let’s say that quantity ought to be between 50-75 characters. In different phrases, we should pack not more than 75 characters on a line, and we are able to do this with the ch
unit, which is predicated on the 0
character’s measurement for no matter font is in use.
p {
width: min(100%, 75ch);
}
This code principally says: get as huge as wanted however by no means wider than 75 characters.
Sizing Recipes Primarily based On min()
Over time, with loads of tweaking and modifying of values, I’ve drafted a listing of pre-defined values that I discover work nicely for responsively styling totally different properties:
:root {
--font-size-6x: min(7.5vmin, calc(2rem + 1.2vmax));
--font-size-5x: min(6.5vmin, calc(1.1rem + 1.2vmax));
--font-size-4x: min(4vmin, calc(0.8rem + 1.2vmax));
--font-size-3x: min(6vmin, calc(1rem + 0.12vmax));
--font-size-2x: min(4vmin, calc(0.85rem + 0.12vmax));
--font-size-1x: min(2vmin, calc(0.65rem + 0.12vmax));
--width-2x: min(100vw, 1300px);
--width-1x: min(100%, 1200px);
--gap-3x: min(5vmin, 1.5rem);
--gap-2x: min(4.5vmin, 1rem);
--size-10x: min(15vmin, 5.5rem);
--size-9x: min(10vmin, 5rem);
--size-8x: min(10vmin, 4rem);
--size-7x: min(10vmin, 3rem);
--size-6x: min(8.5vmin, 2.5rem);
--size-5x: min(8vmin, 2rem);
--size-4x: min(8vmin, 1.5rem);
--size-3x: min(7vmin, 1rem);
--size-2x: min(5vmin, 1rem);
--size-1x: min(2.5vmin, 0.5rem);
}
That is how I approached my experiment as a result of it helps me know what to succeed in for in a given state of affairs:
h1 { font-size: var(--font-size-6x); }
.container {
width: var(--width-2x);
margin: var(--size-2x);
}
.card-grid { hole: var(--gap-3x); }
There we go! We now have a heading that scales flawlessly, a container that’s responsive and by no means too huge, and a grid with dynamic spacing — all and not using a single media question. The --size-
properties declared within the variable checklist are probably the most versatile, as they can be utilized for properties that require scaling, e.g., margins, paddings, and so forth.
The Closing End result, Once more
I shared a video of the outcome, however right here’s a hyperlink to the demo.
See the Pen [min() website [forked]](https://codepen.io/smashingmag/pen/wvVdPxL) by Vayo.
So, is min()
the be-all, end-all for responsiveness? Completely not. Neither is a weight-reduction plan consisting completely of container question models. I imply, it’s cool that we are able to scale a complete webpage like this, however the internet is rarely a one-size-fits-all beanie.
If something, I believe this and what Chris demoed are warnings in opposition to dogmatic approaches to internet design as a complete, not solely distinctive to responsive design. CSS options, together with size models and features, are instruments in a bigger digital toolshed. Relatively than getting too cozy with one characteristic or method, discover the shed since you may discover a higher instrument for the job.

(gg, yk)