I have started using a technique for handling vertical spacing in front-end design that uses transparent <hr>
for spacing elements. I know this owes me the hate of the majority of the web community, but I still think it's a great way to handle special cases. Here are the benefits:
<hr>
is a self-closing tag, so it is kind on the markup<hr>
that only takes space does not oppose the semantic meaning of the element.I am very much aware of the needed separation between markup and style. However, vertical spacing between elements in responsive design is sometimes tedious to do, and often comes with a higher price than semantic markup in my opinion.
A common approach is to handle special cases with manual styling: when component-based classes such as .my-special-recurring-element
is not precise enough (let's say this particular one is too close to the element below it), well add an id #special-element-that-requires-spacing
and style it manually, which becomes very hard to maintain:
/* Ensure that the special element is not too close to the footer in mobile */
#special-element-that-requires-spacing {
margin-bottom: 1rem;
}
@media screen and (min-width: 640px) {
#special-element-that-requires-spacing {
margin-bottom: 0;
}
}
This is why CSS utility toolkits such as Tachyons and Basscss have became more popular in the recent years. It allows tweaking vertical spacing with inline classes, with the added benefits of direct responsiveness handling. We can now write our HTML like this (example in Tachyons):
<div class="my-special-recurring-element mb1 mb0-ns"></div>
where .mb1
roughly means apply a margin-bottom of 1 on our size scale and mb0-ns
means apply a margin-bottom of zero in non-small viewport width. This is definitely more practical for front-end design, but it often becomes a cluttered mess that - in my opinion - defies the markup-styling separation more than anything. Using such toolkits, we often end up with markup like this:
<div class="ph2 pv3 pv2-m pv1-l mb2 mb2-ns"></div>
So what we're doing here is practical and quick, but unmaintainable. It also doesn't help us with a very common use case: “Where do I put the space? Do I add a padding-bottom
to this? A margin-top
to this? Oh, I need to remove the padding here on mobile, but the margin here on non-small”, etc., etc.
Enter the <hr>
space. We can now put a single <hr class="space-1">
between the two elements we want to separate, and have consistant, readable, maintainable and semantic spacing between elements that clutters neither the markup nor the stylesheet.
hr.space-1 {
background: transparent;
color: transparent;
margin: 0;
height: 1rem;
}
@media screen and (min-width: 640px) {
hr.space-1 {
height: 1.5rem;
}
}
@media screen and (min-width: 1200px) {
hr.space-1 {
height: 2rem;
}
}
Is it really that much of a crime? What are the drawbacks you see with this approach?
It's not a crime at all. I'd do it with a div and a class, but you're right, it's more "semantically proper" with a <hr>. There was a tag called <spacer> and it served exactly this purpose; my only problem with <hr> is that it can only add vertical space, it's not really useful for horizontal situations. But that's a rare case anyway.
HTML5 is still not perfect for totally and absolutely semantic markup; there are tags with dashes that could solve this problem but:
http://caniuse.com/#search=custom
...they're not really supported. Not yet. However beautiful a <vertical-space> tag would be, you just can't do it right now.
So don't be scared of using some not-so-semantic markup in your code; it will evolve soon as HTML5 support increases. And don't listen to the standard-or-die kind of freaks. They are in a temporary state of learning.