Dirty tricks in CSS are very useful; where would YouTube players be without using padding–bottom: 56.25%
to create a 16:9 ratio? I assembled a list of my favourite dirty tricks for you!
1. Min margins
This one gets me a lot of dirty looks, but that doesn't mean it's wrong.
If you add items that vary in width in a row with a (quite large) gap in between it can be very hard to determine when those items won't fit on the same row anymore, using a margin on only one side can also mess with centered items or make items break too soon.
.row {
display: flex;
flex-wrap: wrap;
margin: 0 -2rem;
}
.column {
margin: 10px 2rem 0; // ensures a 4rem gap between items
}
2. Extending the clickable area
I've talked about this in a previous article, because pseudo elements like ::before
on an anchor tag (<a>
) inherit the click-ability of its parent you can use it to extend the clickable area of a link.
Make sure you add position: relative
on the element you want to use as reference for the clickable area.
In the following example I used position: relative
to the entire .list-item
and position: absolute
to the pseudo element with either top
, left
, right
& bottom
set to 0
, or width: 100%; height: 100%;
Some developers would add an anchor link around the entire list item, this is really annoying to people using screen readers. It's also annoying to style, because you'd have to set the text-transform
and color
property to overwrite standard link behaviour on all text.
This trick works on buttons as well🤓
3. Writing mode
Writing mode is a css property used to set the writing direction. This is of course meant for languages that have a different writing direction than left to right, it's also very useful to style text that has been rotated 90deg.
When you use transform
to rotate text 90deg padding-left
will appear on the top of the element (which is probably what you would expect) but the container also gets a weird width; see the codepen below when you click on the texts. You won't get this with writing-mode: vertical-lr;
. The big downside of using writing mode instead of transforms is that you can't animate the rotation between two writing modes.
4. Padding bottom
For some reason when you use percentages for padding-bottom
they are not based on the height
of the element but the width
. This is very useful in styling YouTube embeds since you probably want it to take up 100% of the available width, but you can't always be exactly sure how wide that space is. Using height: 56.25%
(16/9) won't work, but adding padding-bottom: 56.25%
will!
Top comments (21)
Nice. Did not know the trick to expand the clickable area!
It's my favourite thing, so useful!
Nice trick!
btw I'd avoid to overlap other texts otherwise they become unselectable
True! This is a big downside to using before
In that case maybe it's better to wrap the whole element in a
a
tag :)You can also use a container around selectable text and set it to
position: relative: z-index: 1
to bring it above the link click area ;) It removes the text from being part of the click area but I would suggest selectable text is a higher priority and you still get the benefit of the rest of the card becoming clickable.Be careful with "trick 2". It makes it harder to select the text (you can only copy it if you select from the outside, not in the usual style of having the cursor on top of the word you want to select).
Thank you for the article! It's right on time as I will need to use 2 point today to extend clickable area of the button to the whole parent element.
Please don't hurt the web accessibility.
As she mentioned, it's bad for screen readers.
Hey, Ankit,
I understood the full paragraph differently:
This paragraph means to me that the alternative to
::before
solution is to wrap the entire content in a<a>
tag. And this<a>
method is bad for accessibility and screen readers.The
::before
method is actually suitable for accessibility (neutral, doesn’t affect it).Please tell me if that makes sense.
ohh alright. My bad. Thanks for making it clear.
No worries! Thank you for asking—accessibility is an important topic!
The vertical padding one is actually a side effect of units in general: percentage units tend to be based on the width of the containing element when there is no other basis for determining them.
It's very handy for sizing things like a video player container so the page doesn't jump around while it loads, and also for making such players responsive.
Negative margins are one you have to be careful with, though - if you happen to have an element at the root of a scrolling container (including the main viewport) with negative horizontal margins, you will overflow in the horizontal direction resulting either in awkward horizontal scrollbars or, on a phone or tablet, a page that scrolls left/right without apparent reason.
With the exception of #4, not one of these would pass our code review. Don't get me wrong: I've used all of them, and WAY dirtier hacks besides, but the bottom line is none of them are NECESSARY anymore.
1 Or you COULD use the included display:flex; and related properties, and maintain both readability and semantic syntax.
2 Could do... or instead use the again-included FIGURE html element ("represents self-contained content, potentially with an optional caption, which is specified using the FIGCAPTION element. The figure, its caption, and its contents are referenced as a single unit.") and set a global text-decoration:none; to figcaption. To avoid annoyance.
3 Talk about screwing up some parsers! Try playing with those properties then handing it to someone for machine translation!
If you're concerned about animating the rotation, the transform-origin property is your friend. As to the non-intuitive cardinal directions, if you DO zero out the origin (transform-origin: 0 100%; seems to be most intuitive for most English speakers I've interfaced with. When used on the word "EXAMPLE" it would place origin where you'd expect it, bottom left of the first 'E'. "0 0" will put it at the top-left), as well as establishing the fixed ratio of the dimensions of the text ("position: absolute; font-size: XXXrem; line-height: XXXrem;", where both XXX's are the same value) you'll have no trouble with your mental model when it comes to unexpected orientations.
4 The reason it's based on width has to do with the mapped logical properties "padding-block-start" and "padding-block-end", which themselves have to do with the directionality (direction the language in question is read, like RTL/LTR) and orientation of the text (it's rotation) - the stuff you're mucking about with in #3 - and how it correlates to the correct rendering of the box model output. This is largely a legacy throwback to IE 5/6's need for "layout" on an object if I recall, but it's been years since I've paid attention to those.
Since you're USING a browser with such an implementation inbuilt (and because you've absolutely positioned the elements in #3, functionally removing them from that "layer" of the model) you don't see the layout butchery that takes place if it DIDN'T create these logical properties on the fly.
The "padding-bottom aspect ratio trick" was introduced by Thierry Koblentz (he called them "Intrinsic Ratios") back during his time with Yahoo in May of '09, where he leveraged this behavior for that exact purpose. The article is still floating around the web somewhere; I referred one of our JD's to it only a few months ago.
I suspect that the web's glacial speed to update fundamental standards/embrace deprecation (why we STILL support IE AT ALL, instead of just displaying a "Upgrade to a Real Browser" message, web-wide) is why it's never been corrected. Besides: in fairness, it works, and new devs are being taught it now as "expected behavior".
I've never heard anyone call it "min margins" before. It's negative not minimum, and it makes debugging someone else's code very difficult. I've worked on sites that use the trick extensively and it's a crapshoot as to which element you get when you click "inspect"!
Told you it would get you dirty looks to use it. ✌️
English is not my first language FYI, in Dutch we use it as minus. I have no problem inspecting the right element though, cmd shift c and click the button ;). I would get you having some trouble inspecting the expanded clickable pseudo elements. These examples aren’t meant to be pretty, it’s why I call them dirty tricks ;)
Not sure about the min-margins one. It could result in an unnecessary horizontal scroll bar if the viewport is narrow. But the others are good.
You could add an overflow hidden, or make sure the min margins don't outgrow the padding around the items on mobile, but you make a solid point that it's not that automatic
The problem with using
overflow:hidden
is that if you've got something else on the page that genuinely needs horizontal scrolling, like a wide table, then that will get truncated.For what it's worth, here's how I'd solve the problem, using wide spaces characters to make the gap between the anchors.
Nice article. Thanks. Just tried the "expand clickable area.".
The second item is really awesome! I didn't know until now.