CSS

The :focus-within pseudo class

The :focus-within pseudo class becomes active when an element itself has focus or if any of its descendants does.

Take for example the following HTML code:

HTML

<div class="container" tabindex="0"> 
  <label for="text">Enter text</label> 
  <input id="text" type="text" /> 
</div>

and the following CSS:

CSS

.container:focus-within { 
  background-color: #aaa; 
}

If the div with the class .container receives focus (it can in this case as it has a tabindex of 0, this is purely for example purposes), it will have a background colour of #aaa.

But it will also have a background colour of #aaa if any of its descendants have the focus. So if the <input> receives focus, then the div’s background will also be #aaa.

This will remove the need for JavaScript that is often used to achieve this effect.

Tags: 

CSS Ruleset Terminology

An inforgraphic demonstrating the various parts of a CSS rule and their names. See the text following this image for more information.

If you ever wanted a mini-cheat sheet for what every part of a CSS rule is called, here it is:

  • The whole thing is a ruleset.
  • The curly braces and everything inside is a declaration block.
  • The bit before the opening curly brace is a selector.
  • Each key/value pair, as separated by a colon and ending in a semicolon, is a declaration.
  • In those key/value pairs, the key is a property (or property name), and the value is a value (or property value).

Tags: 

Text stroke with CSS

The text "Here is some special text" with the words "some special" having a stroke applied to them, and a base inner colour matching the background.

There is a non-standard way to stroke HTML text (SVG has a standard way). It’s not particularly new. There are -webkit- and -moz- prefixes for it. Jen Simmons recently posted about it, with an example:

CSS

span {
     -moz-text-fill-color: #fde;
  -webkit-text-fill-color: #fde;
     -moz-text-stroke-color: #666;
  -webkit-text-stroke-color: #666;
     -moz-text-stroke-width: 2px;  
  -webkit-text-stroke-width: 2px;
}

And she’s right:

This CSS isn’t fully-baked or fully-supported. But it’s good enough to be used today, especially since it’s simply offering a visual enhancement. It’s not mission critical to making a website usable.

I’d only perhaps add that if you were going to do something like add a stroke around white text, you could wrap it in a @supports to be extra sure it’ll be OK (just in case a browser exists that supports text-fill-color but not text-stroke-color) :

CSS

@supports 
  ((-webkit-text-stroke-color: #666)
  and
  (-webkit-text-fill-color: white))
  or
  ((-moz-text-stroke-color: #666)
  and
  (-moz-text-fill-color: white)) {
  span {
       -moz-text-fill-color: white;
    -webkit-text-fill-color: white;
       -moz-text-stroke-color: #666;
    -webkit-text-stroke-color: #666;
       -moz-text-stroke-width: 2px;  
    -webkit-text-stroke-width: 2px;
  }
}

See the link for more tricks, and the comments make a good point that you don’t have to use text-fill-color if you’re using @supports: just use color.

Tags: 

Dealing with long words in CSS

CSS

.hyphenate {
  overflow-wrap: break-word;
  word-wrap: break-word;
  -webkit-hyphens: auto;
  -ms-hyphens: auto;
  -moz-hyphens: auto;
  hyphens: auto;
}

This solution will show hyphens for every browser supporting it and will break lines in every other browser – perfect. [Although] I have tested this solution in 26 different browsers I am still not sure this will work 100% – if you find any edge case please let me know.

Tags: 

Expand last row of wrapped flex items to fill entire row

Thanks to Jonathan Snook, I’ve learnt that we don’t need quantity queries to create a balanced grid. Quantity queries are very powerful, but so is Flexbox. If we just want all the items in the last row to fill the space, regardless of how many there are, then Flexbox can take care of this. But if we want to add additional styles to the items, we still need quantity queries.

This is the grid we want to achieve:

A wrapped grid of flexbox items. The first two rows have four items each, stretching to the full width of the container. The third row only has three items, but they also stretch to the available space.

Here’s the Flexbox magic.

The container needs to have the property display: flex; and the items need to be wrapped using flex-wrap: wrap;

CSS

.list {
    display: flex;
    flex-wrap: wrap;
}

Now here’s the clever bit. We can set an initial width to the items (in this case flex-basis: 23%;) so that each item will always get a width of 23% unless otherwise stated in the CSS. flex-grow: 1; tells the items to grow and fill the space in the row.

CSS

.list-item {
    ...
    flex-basis: 23%;
    flex-grow: 1;
}

So, thanks to flex-grow, no matter how many items are in the last row, they will always fill the space. Works like magic! It’s amazing how much can be achieved with so little CSS.

Tags: 

Fixed and sticky headers and in-page anchors

I made a little tweak to The Session today. The navigation bar across the top is “sticky” now—it doesn’t scroll with the rest of the content.

I made sure that the stickiness only kicks in if the screen is both wide and tall enough to warrant it. Vertical media queries are your friend!

But it’s not enough to just put some position: fixed CSS inside a media query. There are some knock-on effects that I needed to mitigate.

I use the space bar to paginate through long pages. It drives me nuts when sites with sticky headers don’t accommodate this. I made use of Tim Murtaugh’s sticky pagination fixer. It makes sure that page-jumping with the keyboard (using the space bar or page down) still works. I remember when I linked to this script two years ago, thinking “I bet this will come in handy one day.” Past me was right!

The other “gotcha!” with having a sticky header is making sure that in-page anchors still work. Nicolas Gallagher covers the options for this in a post called Jump links and viewport positioning. Here’s the CSS I ended up using:

CSS

:target:before {
    content: '';
    display: block;
    height: 3em;
    margin: -3em 0 0;
}

I also needed to check any of my existing JavaScript to see if I was using scrollTo anywhere, and adjust the calculations to account for the newly-sticky header.

Anyway, just a few things to consider if you’re going to make a navigational element “sticky”:

  1. Use min-height in your media query,
  2. Take care of keyboard-initiated page scrolling,
  3. Adjust the positioning of in-page links.

Tags: 

Style List Markers in CSS

It’s a perfectly reasonable to want to style the marker of list items. You know: blue bullets with black text in an unordered list. Or red counters with knockout white numbers in an ordered list.

There is a working draft spec that defines a ::marker pseudo-element that would give us this control.

CSS

/* Not supported anywhere; subject to change */
li::marker {
  color: blue;
}

It’s possible to do this styling now, though, thanks to CSS counters. The trick is to remove the list-style, then apply the markers through pseudo-element counters.

CSS

ol {
  list-style: none;
  counter-reset: my-awesome-counter;
}
li {
  counter-increment: my-awesome-counter;
}
li::before {
  content: counter(my-awesome-counter);
 
  /* Style away! */
 
}

Tags: 

Pages