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;
}