Hướng dẫn hack dead of the tagre wp
I had a little situation the other day where I needed to make one of those aspect-ratio friendly boxes. This isn’t particularly new stuff. I think the original credit goes as far back as 2009 and Thierry Koblentz’s Intrinsic Ratios and maintained popularity even for other kinds of content with articles like Uncle Dave’s Ol’ Padded Box.
Let’s go on a little journey through this concept, as there is plenty to talk about.
The Core Concept: padding in percentages is based on width
Even when that is a little unintuitive, like for vertical padding. This isn’t a hack, but it is weird:
2 is based on the parent element’s
3. So if you had an element that is 500px wide, and
1 of 100%, the
1 would be 500px.
Isn’t that a perfect square, 500px × 500px? Yes, it is! An aspect ratio!
If we force the height of the element to zero (
Now imagine instead of 100% top padding, we used 56.25%. That happens to be a perfect 16:9 ratio! (9 / 16 = 0.5625).
Now we have a friendly aspect ratio box, that works well in fluid width environments. If the width changes, so does the height, and the element keeps that aspect ratio.
Use case: a background-image
Perhaps we’ve made a typographic lockup. It’s for the title of an article, so it makes sense to use an
We can make that
7 tag the aspect ratio box and apply the lockup as a background image.
But I lied about that aspect ratio up there. It’s not actually a 16:9 image. I just downloaded that graphic off a stock photography site. It happens to be an SVG with a
9 which means it’s essentially an 1127.34 × 591.44 image in terms of aspect ratio. Or it could have been a 328 × 791 image.
I’d say it’s very common for any random image not to fit into a very specific pre-defined aspect ratio…
The Math of Any Possible Aspect Ratio
Perfect squares and 16:9 stuff is great, but the values used for those are just simple math. An aspect ratio can be anything, and they commonly are completely arbitrary. A video or image can be cropped to any size.
So how do we figure out the padding-top for our 1127.34 × 591.44 SVG above?
One way is using
0, like this:
It was expressed to me not long ago that using
0 here may be “slower”, but I’ve never seen any evidence of that. I imagine that yes, the computer does need to calculate something, so in a head-to-head battle against a situation where it doesn’t, calculating is slower. But a math problem doesn’t seem like too much work for a computer. For example, the popular Intel Pentium III (released in 1999) could do 2,054 MIPS or “Millions of instructions per second”, so it would make imperceptively quick work of a division problem. And now chips are 50× faster.
If we were using a preprocessor like Sass, we could do the calculation ahead of time:
Either way, I’m a fan of leaving the math in the authored code.
How do you put content inside if padding is pushing everything down?
We hid the content in the demo above, by letting the content get pushed out and hiding the overflow. But what if you need an aspect ratio box while keeping content inside of it? That’s slightly trickier. We’ll need to position it back up into place. Absolute positioning can be up for that job.
Say we’re just using text alone now, but still want the aspect ratio box. We’ll need an inside wrapper for the absolute positioning. Let’s get specific with our classnames:
Then do the positioning:
Just for fun, let’s go full blast here and center that text and size it so it scales with the box:
Few more classes to style:
Use Case: Video
This is probably the
1 most common and practical use case for all this aspect ratio box stuff. HTML5
2 isn’t an issue, as it behaves as if it has an aspect ratio just like
3s do. But a lot of video on the web arrives in
4s, which do not scale with an aspect ratio.
This is exactly what FitVids is all about. It finds videos on the page, figures out their unique aspect ratios, then applies these same CSS concepts to them to make them fluid width while maintaining their unique aspect ratios.
But… what if there is too much content?
Back to arbitrary (probably textual) content for a bit.
We’re essentially setting heights here, which should always flash a blinking red light when working with CSS. The web likes to grow downward, and setting fixed heights is an enemy to that natural movement.
If the content becomes too much for the space, we’re in Bad Design territory:Bad Design Territory
Maybe we could do something like
5 but that might be Awkward Design Territory.
The Pseudo Element Tactic
This is what has become, I think, the best way to handle an aspect ratio box that has completely arbitrary content in it. Keith Grant has a good writeup on it. Marc Hinse had an explanation and demos back in 2013.
With this technique, you get the aspect ratio box with less markup, and it’s still safe if the content exceeds the height.
The trick is to apply the % padding to a pseudo-element instead of the box itself. You float the pseudo-element, so the content inside can be inside nicely, then clear the float.
See how it’s safer:
And a video:
Using Custom Properties
This is perhaps the coolest idea of all!
Thierry Koblentz recently wrote this up (Removing link as Thierry’s site is dead.), crediting Sérgio Gomes for the idea.
To use it, you set a custom property scoped right to the element you need it on:
The CSS that styles this is gosh-danged genius:
Allow me to quote Thierry’s step-by-step explanation:
Other Ideas & Tools
Lisi Linhart tipped me off to Ratio Buddy, which is super cool:
Notice that it uses a pseudo-element, but then still absolutely positions the inside container. That’s kinda weird. You’d probably either skip the pseudo-element and put the padding directly on the container, or float the pseudo-element so you don’t need that inner container. Still, I like the idea of a little generator for this.
I’ve actually seen quite a bit of real world usage of aspect ratio boxes over the years. Feel free to share if you’ve had some experience!