Styling Code In and Out of Blocks

Avatar of Chris Coyier
Chris Coyier on

Take the pain out of building site search with the Algolia hosted API. Start free now!

There is a <code> tag in HTML. I literally just used it to wrap that tag in the previous sentence — so meta. It is an inline-by-default element that denotes any sort of code. It has default (user agent) styles that apply a monospace font-family, which feels like a fine default (as it’s true, most code is looked at in monospace).

/* User agent styles in all browsers */
code {
  font-family: monospace;
}

It’s likely something that you’ll style with the tag itself as well in your stylesheets. It’s just one of those elements where it seems far more natural to just use it raw, as opposed to resetting it to no styles and opting into styles with a class.

/* You'll probably do this: */
code {
  /* custom styles */
}

/* Or maybe scope it to something like: */
article code {

}

/* It seems less common and more annoying to do this: */
code {
  /* reset styles */
}

code.some-class {
  /* opt-in styles */
}

On this site right now (v18), I apply some modest styles and scope some of them within textual elements:

/* For all <code> */
code {
  font-family: MyFancyCustomFont, monospace;
  font-size: inherit;
}

/* Code in text */
p > code,
li > code,
dd > code,
td > code {
  background: #ffeff0;
  word-wrap: break-word;
  box-decoration-break: clone;
  padding: .1rem .3rem .2rem;
  border-radius: .2rem;
}

One thing this helps with is, say, this:

<h3>The <code>.cool</code> Class</h3>

My styles will still make that a nice monospace font, size it to be the same as the header, but not apply the background color and padding stuff I like for code within text.

The bigger deal when it comes to scoped-styles for <code> though is this very common markup:

<pre><code>
  example code block
</code></pre>

The <pre> tag is important for displaying code blocks, as it respects whitespace in the HTML. But semantically, it just means “pre-formatted text.” If it’s a code block, there should be a <code> tag involved too. But <code>, remember, is an inline element. Plus, it’s highly likely that how you want it to look within a sentence is quite different from how you want it to look in a block.

Jason was tweeting about this the other day:

https://twitter.com/jlengstorf/status/1343022493984989186

There was a moment of confusion in the thread where:

/* this was working */
.post :not(pre) code {

}

/* and this was not */
:not(pre) code {

}

The problem with the second “at the root” selector is that :not(pre) will match things (like the <body>) and thus apply those styles. Within the post (the first example), it’s only going to select things — like paragraph tags and images and such — and thus behave more expectedly. I think that’s a fine approach. It’s just an alternative way of doing the scoping on that <code> tag such that it doesn’t get certain styles while it’s within specific elements, because the <pre> tag being the primary concern.

I have lots code blocks on this site, so I try to be a bit extra protective. I specifically style the <code> elements that within <pre> tags with a lot of styles to get them how I want, and potentially fight against any other undesirable styles they may have. Stuff like:

pre code {
  display: block;
  background: none;
  white-space: pre;
  -webkit-overflow-scrolling: touch;
  overflow-x: scroll;
  max-width: 100%;
  min-width: 100px;
  padding: 0;
}

My actual styles are a bit more verbose, even than that. There is nothing clever about that snippet. I’m just pointing out that I apply a pretty good heap of styles to code blocks to make darn sure they come out right.

I find it interesting how the <code> element is somewhat unique in just how differently we tend to style it depending on context.