CSS (Step 1)

Now that we’ve got content out of the way (I know, I know, content is hard, and pulling it out of clients—or even your own brain—can be even harder), it’s time to make your website look good. We’ll consider a semi-standard blog type site, with posts as excerpts from classic works of fiction. Don’t worry about where the content comes from, or how to pull it from a database or any fancy stuff yet—we’ll get there.

Again, I won’t be covering the details of syntax, rather, I’ll be giving an overview of design elements and how to use them such that you won’t be too surprised at the results. Also, I’ll cover popular designs and how to implement them.

Step one implements some basics, but it’s kind of a hack job. Let’s see how to make it better, and better looking.

Notice that the gradient fill, from a whitish to a blue tint, gets darker as you scroll the page. It might look better if we could fix it, so that the text would scroll but the background would be stable.

Notice that, while the header stays fixed, its background is matched to the original white color. And the footer is matched to the original bluish color, but doesn’t extend all the way to the edges of the browser window.

I used the newish details element to display/hide the author’s name and publication date, but it automatically inserts the word “Details” and a glyph for showing and hiding the info—we can do better.

Let’s make a complete list of what we’ll update:

  • Stable gradient fill background
  • Retain gradient fill for header, but keep it sticky
  • Fade text into header when scrolling
  • Modify “details” element styling
  • Floating “back-to-top” button
  • Sticky chapter titles
  • Simpler, or more flexible, or at least easier to comprehend, drop-cap styling (or raised-cap, or block cap)
  • Use of relative units instead of pixels

The first bit–the fixed gradient–turns out to be easy to fix! Just add

background-attachment: fixed;

But the header looks more out of place with a solid background. The reason it’s solid in the first place is that, without setting a background for the header (comment out that line and try it yourself), the text scrolls right through the header and it looks even worse. What if we copy the body styling for the background image? Turns out, this works fairly well, but now we have a new problem, or at least something we can probably improve upon: the text just disappears as you scroll, a sharp line across the screen.

This, as you might guess, requires a bit more work. Also in the header, add this:

-webkit-mask-image: linear-gradient(rgba(0,0,0,1) 125px,transparent);
mask-image: linear-gradient(rgba(0,0,0,1) 125px,transparent);

This one still requires a prefix in Chrome, at least. What these lines do is add a mask: black at the top down to 125 pixels, fading to transparent. But as it is a mask, the black acts as a filter to block content underneath from showing, save the content to which the mask has been applied, which, in this case, is the original gradient background.

The “Details” element. Could use a bit more flair, I think! First, we add a “summary” tag inside to change the text “Details” to whatever we want—in this case, “Story Info” is as good as anything.

For the rest, we’re going to make things simple. Ish. Instead of the “twisty”—the turning triangle that indicates whether the details element is open or closed—we’ll use a plus and a minus sign, bold, and in red. In Firefox that’s fairly simple, but Chrome makes things a tad difficult.

details > summary {
  list-style:none;
}

details > summary::-webkit-details-marker {
  display: none;
}

summary:before {
  float:left;
  margin-top:-0.5ex;
  padding:0;
  content:'+';
  width:20px;
}

details[open] summary:before {
  content: '-';
}

Highlighting the important bits here, the list style after the details > summary selector is the standards-compliant way of removing the twisty; the pseudo-element -webkit-details-marker is for Chrome. The rest should be fairly self-explanatory: placement of the content within the summary element and its size, and what to show when the element is in its open state. For our example, I also threw a border around it and added some basic styling to the book title, author, and publication date.

How about a “back to top” button? The link href is fairly well-established: "#", but how do we place an element so you can click on it no matter how far down (or up) the page you’ve scrolled? Can it even be done with just CSS?

The answer to that is usually, “Of course!” But, again, as usual, if you want to do slightly fancier things, you have to use JavaScript. We’ll stick to the CSS for now. And this can be done (almost) entirely in CSS, too! Add this code:

#toTop {
  display:block;
  position:fixed;
  bottom:30px;
  right:30px;
  z-index:99;
  border-radius:25px;
  width:50px;
  height:50px;
  background-color:$darkblue;
  color:$offwhite;
  text-align:center;
  line-height:50px;
}
#toTop:hover {
  background-color:$red;
}

The highlighted lines are the important ones. Everything else is looks. We want it to be in the same position, thus “fixed” there, and we want it on top of anything else we put on the page, so a z-index of 99 should do the trick. If you’ve got more layers, maybe tack on another 9 or two.

Nothing will show up until you add an appropriately id’d div in the html also:

<a href="#"><div id="toTop">Top</div></a>

You can put the anchor inside or outside—in this case I prefer outside so I can click anywhere on the element to take me to the top.

You’ve probably seen it before and wondered, “how can I do that”? Every time you scroll to a new article, the title stays at the top, until a new one comes into view. As usual, this is something you can do with only CSS!

article > h3 {
  position: sticky;
  top:125px;
}

At this point, I’ll leave it as an exercise to the reader to handle the fading and text overlapping. There are a few solutions, and the neatest is probably to make the chapter title/heading a full-width banner, and to handle the fading below that. This article also shows off some other cool things you can do with position: sticky.

Nearing the end! Drop caps are a bit of a tricky thing in CSS. You might be tempted to throw in just

article p:first-of-type:first-letter {
  float: left;
  font-size: 5em;
}

and call it a day, but if you pay attention (and this will vary by font), the letter isn’t aligned with the top of the paragraph, and it looks a bit tacky.

vertical-align:text-top;

won’t do the trick either, unless you throw in an extra element before the paragraph for the first letter (it should work inside, but it’s not doing what I expect, at least on CodePen). Honestly, for now the best you can do here is experiment. I added

line-height:60px;

and got what I was looking for.

In the far-flung future, people will be able to use

initial-letter:3;

to achieve roughly the same result.

If you want to be ready for that, use CSS feature queries!

@supports (initial-letter:1) or (-webkit-initial-letter:1) {
  article p:first-of-type:first-letter {
    -webkit-initial-letter:3;
    initial-letter:3;
  }
}

The main reason I’m so insistent on styling with :first-letter (contrary to the advice given in this article) is because I do have visually impaired friends and relatives. While I’m fairly certain these individuals use a computer minimally, if at all, I’m sensitive to the ease of use for them. I do intend to make one of these articles focused specifically on accessibility, but for now, take the exhortation to use semantic elements as much as possible, and ensure your site is usable sans any styling.

The last thing I’m going to cover in this “basics” article is length units. Despite the fact that I used pixels throughout my stylesheet, it’s kind of bad form. With “retina” displays and different browser interpretations, a pixel isn’t always a pixel anymore. Also, with modern CSS, we have a lot more units available to us! The first 7 of the long list below are the ones to avoid, especially when defining font sizes. Some of them are more reliable than others. Nobody supports “cap”, “ic”, “ih”, “vb”, or “vi” yet; support for “Q” is spotty, and support for “vmin” and “vmax” is inconsistent. Even so, you have a lot of options!

  • px (pixel, often, but not always, defined as 1/96in)
  • in (inch)
  • cm (centimeter)
  • mm (millimeter)
  • Q (1/4mm)
  • pc (pica, defined 12pt)
  • pt (point, defined as 1/72in)
  • em (calculated font size of the element)
  • ex (ideally the height of lowercase (Latin) letters in the current font, often equal to 0.5em)
  • cap (cap height of the current font)
  • ch (advance measure of “0” in the current font)
  • ic (advance measure of “水” in the current font)
  • lh (calculated line height of the current font)
  • rem (calculated font size of the root element, <html>)
  • rlh (calculated line height of the root element, <html>)
  • vh (1% of the viewport height)
  • vw (1% of the viewport width)
  • vi (1% of the initial containing block in the direction of the inline axis)
  • vb (1% of the initial containing block in the direction of the block axis)
  • vmin (smaller of vh and vw)
  • vmax (larger of vh and vw)
  • % (percentage)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.