5 Lesser Used CSS Selectors

If you are new to CSS, the selectors you use are probably limited to class names, IDs and generic elements. In fact, there are in total 38 css selectors, varying greatly in complexity.

Here are 5 css selectors you may not have known about, and some use cases for them.

Selector Type Description
foo:empty structural pseudo-class a foo element that has no children
foo::first-letter &foo::first-line pseudo-element the first formatted letter & line of the foo element
foo:not(x) pseudo-class all foo elements except those with the attribute x
foo:lang(de) pseudo-class a foo element in the German language
foo:target pseudo-class a foo element being the target of a referring URI

:empty #

The :empty pseudo-class represents an element that has no children at all. This includes whitespace, text nodes, or an empty child element, but does not include html comments. For example -

<!-- These will satisfy as empty -->
<div><!-- comment --></div>

<!-- These will NOT satisfy as empty -->
<div>  </div>
<div>  <!-- comment -->  </div>

The :empty pseudo-class is useful for elements which are styled in such a way that they appear regardless of whether they have content in them or not.

An example could be alert message boxes. We only want them to appear under certain circumstances, and the text content within them may be dynamically inserted and removed depending on the context. Using the :empty pseudo-class, we can make sure that the box will be hidden when there is no content within it.

.alert {
  background-color: beige;
  border: 2px solid rgb(150, 150, 150);
  border-radius: 5px;
  padding: 5px 10px;
  display: inline-block;

.alert:empty {
  display: none;

Alert Boxes With and Without Using the Empty Selector

::first-letter and ::first-line #

The ::first-letter and ::first-line pseudo-elements represent the first letter and first line of the relevant element. What is great about ::first-line in particular is that it is responsive. As you shrink and enlarge the viewport and the text on the first line increases and decreases, the formatting is applied.

As you would expect, they can be particularly useful when formatting articles. For example -

article::first-letter {
  font-size: 8rem;
  line-height: 1;
  float: left;
  padding-right: 1rem;
  margin-top: -2rem;

article::first-line {
  font-size: 3rem;

Article styled using first-letter and first-line

:not(x) #

The :not pseudo-class allows you to select all elements except those that satisfy a certain condition. This is extremely useful as it helps us avoid having to write extra css to override general styles.

For example, I may want all links on my site to have an underline, except ones which I specify. Normally, I would write -

a {
  text-decoration: underline;
a.no-underline {
  text-decoration: none;

Doing this means that the links with the class .no-underline have the default styling unnecessarily applied to them. Using the :not selector, I can avoid this extra declaration -

a:not(.no-underline) {
  text-decoration: underline;
a.no-underline {
  text-decoration: none;

Wesbos on twitter also recently showed an example of how we can use this selector -

🔥Protip: Use CSS :not() instead of applying and unapplying borders on navigations. Supported wherever last-child is pic.twitter.com/HPJ1Rw3jZH — Wes Bos (@wesbos) June 3, 2015

:lang #

The lang pseudo-class targets elements that have been defined as a specific language. Selecting these elements, we can do a number of things.

1. Add helpful information and/or styling. We can style the section of the page that is in a different language in a special way to make it more clear to users, as well as add helpful information about the section.

*:lang(de) {
  border-left: 4px solid #FFCE00;
  padding-left: 1rem;

*:lang(de):before {
  content: "DE";
  position: absolute;
  top: 0;
  left: -55px;
  width: 40px;
  height: 40px;
  text-align: center;
  padding: 10px 0;
  border-radius: 50%;
  background-color: #FFCE00;

Styling a paragraph in German

2. Use special quotation marks. Different languages use different quotation marks, so it is helpful to be able to use the native quotation marks of the relevant language.

  blockquote:before {
  content: open-quote;
  padding-right: 1rem;

blockquote:after {
  content: close-quote;
  padding-left: 1rem;

blockquote:lang(fr) {
  quotes: '«' '»';

blockquote:lang(zh-Hans) {
  quotes: '「' '」';

Styling Quotation Marks for French and Chinese Languages

3. Apply special fonts. We can also apply fonts or font styles more suited to the language if needed. For example, in Japanese, using italicised letters for emphasis is not suitable. Instead, we can use use the dot style that is common to the language.

em:not(lang(ja)) {
  font-style: italic;

em:lang(ja) {
  font-style: normal;
  -webkit-text-emphasis-style: dot;
  text-emphasis-style: dot;
  text‑emphasis‑position: over right;

Styling emphasis in Japanese language using dots

:target #

The :target psuedo-class represents an element that is the target of a referring URI. For example, if you have a particularly long article broken up into sections, with each section having a unique ID, you can link to that particular section in the URL.

Using the :target selector, you can style whichever section is the current target.

:target {
  border-left: 4px solid rgb(200, 200, 200);
  padding-left: 1rem;

Highlighting the current target

As always, you can view the full code examples on my github repo.

Keep in touch KeepinTouch

Subscribe to my Newsletter 📥

Receive quality articles and other exclusive content from myself. You’ll never receive any spam and can always unsubscribe easily.

Elsewhere 🌐