CSS is hard I
by brico
HTML
<h1>CSS is Hard Vol. I: Be A Good Neighbor</h1>
<p>Say we have a page:</p>
<div class="page">
<div class="header">
<h2>The page has a title</h2>
</div>
<div id="main" class="main">
<p>There is some content.</p>
</div>
<div class="sidebar">
<p>There is a sidebar with some stuff in it.</p>
</div>
<div class="footer">
<p>And a footer. That's it for now.</p>
</div>
</div>
<p>Some people like to set some basic styles for different zones of the page:</p>
<div class="page">
<div class="header">
<h1>A common approach</h1>
</div>
<div id="main" class="main">
<h2>We target ids</h2>
<p>Which represent zones in the page</p>
</div>
<div class="sidebar">
<p>Etc</p>
</div>
<div class="footer">
<p>And so on.</p>
</div>
</div>
<p>Later, I want to add something to the page. A captioned image. </p>
<div class="page">
<div class="header">
<h1>The ID-as-zone approach</h1>
</div>
<div id="main" class="main">
<h2>Later...</h2>
<p>We add something new. A nice captioned image.</p>
<!-- Here is my new thing -->
<div class="captioned">
<img src="https://si0.twimg.com/profile_images/2940708431/842924fb3e2cc1f7fddf1b195c3f6c81.jpeg" />
<p class="caption">
I am soo coool.
</p>
</div>
<p>Bummer, I can't read that!</p>
<p>The #main p rule has a ton of specificity, overriding my .caption's color.</p>
</div>
<div class="sidebar">
<p>Etc</p>
</div>
<div class="footer">
<p>And so on.</p>
</div>
</div>
<p>There must be a better way!</p>
<p>By switching from id-as-zone style to a modular style, I avoid making life harder for myself in the future.</p>
<div class="page">
<div class="header">
<h1>The modular approach</h1>
</div>
<!-- forget IDs for css -->
<div class="main">
...
CSS
/* Our page, with a basic two column layout.
*/
* { box-sizing: border-box; }
.page { width: 100%; background: whitesmoke; border: 1px dashed red; padding: 5px; }
.header, .main, .sidebar, .footer { border: 1px dotted blue; }
.main { float: left; width: 65%; }
.sidebar { float: right; width: 35%; }
.footer { clear: both; }
/* Off I go. To start, I set base typographic
* styles for some zone of the page, taargeting an ID.
*
* We have all done this a million times.
*/
#main h2 {
text-transform: uppercase;
color: grey;
}
#main p {
font-family: arial;
color: #444;
line-height: 1.8;
}
/* Then I want to add a new thing to the main area of the page.
* Here is how i'd like to do it...
*/
.captioned {
display: inline-block;
position: relative;
}
.captioned .caption {
position: absolute;
margin: 0;
padding: 5px;
display: block;
width: 100%;
bottom: 4px;
color: white;
background-color: rgba(0, 0, 0, .6);
}
/* Because of the #main p rule above, I am thwarted
* if I try to put .caption on a <p>.
* To force it to work I would have to change my rule
* for increased specificity...
*
* #main p.caption {}
*
* which would kill its reusability and continue the
* arms race of selector speceficity.
*
* Or if I really got desperate I might resort to
*
* color: white !important;
*
* !important is the nuclear option. It may save you a minute now,
* but it will come back to haunt you. Don't use it unless you
* are way smarter than me and also can predict the future.
*
* Instead, I would rather turn my id-based rules
* into modules that I can apply anywhere I want:
*/
.bodycopy {
font-family: arial;
color: #444;
line-height: 1.8;
}
.shout {
text-transform: uppercase;
color: grey;
}