A CSS trick to add icons to your navigation links in Squarespace

I’ve talked about navigation tricks before in this blog, about how you can add a secondary menu bar to templates that don’t give you that option, and on how you can turn your last link into a button on any template.

But, what if what you want to do is add a little extra to your existing menu?

Something like your brand’s icons to identify each of the different pages your navigation leads to.

Well my friend, if you’re on that boat (pun totally intended, you’ll understand why in a second) you’ve come to the right place, because today you’re going to learn precisely how to add icons to your navigation links in Squarespace.

Alright, let’s get to it!

Adding an icon to each of your menu links

I’ll be working with one of the Brine family templates, Rover, so keep in mind the classes and HTML structure you’ll see on your own site may vary.

And if you want to follow along, here are the exact, adorable, nautical icons I used on this example (hence the very bad pun):

This is the initial menu I’ll be working with. I’ve given it a background color so you can clearly see what we’re doing.

1. Starting menu.png

First thing, we have to find out what class our menu items/links are using.

2. Looking for class name.png
3. Looking at inspect element up close.png

We have that our items are a elements and have a common class of .Header-nav-item as you can see above.

Now, to make sure we only target the nav items of the menu we’re working on and not a secondary one, for example (unless that’s what you’re going for), we’ll have to look for a parent with a class that helps us identify this precise menu.

4. Finding parent container.png

Great, we can see the nav container has a class of .Header-nav—primary so that will work perfectly!

Let’s head over to our Custom CSS window and build our selector:

.Header-nav--primary .Header-nav-item {

}
5. Targeting via CSS.png

Now, just to check I’ll give these items a background color:

6. Testing a random bg color.png


Awesome! We’re good to go.

There are two ways we can give each separate link its own icon:

  • By using their position as reference.

  • By using any unique class, id, or attribute.

We’ll be looking at both approaches in this tutorial, so let’s start with the first one.


Using position as reference

This approach is great if you’re not planning on moving your links around, or if you’re purposefully looking to style whichever item sits on a specific position (like in this post).

Otherwise, you’ll have to tweak your CSS selectors any time you switch up your links, to make sure the icon matches the correct link.

To select an element by its position we can use the pseudo-classes :first-child, :last-child and/or :nth-child(). We’ll be using the latter.

So, if I wanted to add that red background only to the first menu item of my navigation, I’d have to target the item in the first position, :nth-child(1), which translates to:

.Header-nav--primary .Header-nav-item:nth-child(1) {
  background: red;
}
7. Selecting only the first one.png

And if I wanted to target the one in the second position, I’d simply need to change the 1 for a 2:

.Header-nav--primary .Header-nav-item:nth-child(2) {
  background: red;
}
8. Selecting only the second link.png

And what about the last one? We could go with :last-child or simply keep counting:

.Header-nav--primary .Header-nav-item:nth-child(4) {
  background: red;
}
9. Selecting the last link.png

Ok, awesome!

Now, let’s move onto actually adding the icon to each link. For this, we’ll be creating a pseudo-element.

We can use ::before so it sits right before the actual text of our link, and we’ll start with the first link for Home:

.Header-nav--primary .Header-nav-item:nth-child(1)::before {
  
}

Now, let’s add in the basic declarations we need to create our empty container (the content property set to nothing, a bit of height and width, and inline-block to make sure our icon sits next to our text):

.Header-nav--primary .Header-nav-item:nth-child(1)::before {
  content: '';
  height: 30px;
  width: 30px;
  display: inline-block;
}

I’m also going to give it a background color so we can see it:

11. Pseudo element basics.png

Nice! Let’s go ahead and take advantage of the fact we’re making our pseudo-element an inline-block to use vertical-align and have our text and little box centered vertically:

.Header-nav--primary .Header-nav-item:nth-child(1)::before {
  content: '';
  height: 30px;
  width: 30px;
  display: inline-block;
  background: red;
  vertical-align: middle;
}
12. Vertical alignment.png

Ok! And how about we give this red square some margin to the right to make some room:

.Header-nav--primary .Header-nav-item:nth-child(1)::before {
  content: '';
  height: 30px;
  width: 30px;
  display: inline-block;
  background: red;
  vertical-align: middle;
  margin-right: 5px;
}
13. Setting a margin.png

Awesome! Our container is now ready for our image.

I’ll remove the background color and substitute it for a background image url:

.Header-nav--primary .Header-nav-item:nth-child(1)::before {
  content: '';
  height: 30px;
  width: 30px;
  display: inline-block;
  background: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2cb8e5e5f04e7d4aaddc/1559047353004/iconfinder_lighthouse_boat_sea_summer_vacation_holidays_3405125.png');
  vertical-align: middle;
  margin-right: 5px;
}
14. Adding the bg image.png

We can see our image is there, but it’s getting cut off because it’s too big for our container.

Let’s fix that by setting the magical background-size: contain;

.Header-nav--primary .Header-nav-item:nth-child(1)::before {
  content: '';
  height: 30px;
  width: 30px;
  display: inline-block;
  background: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2cb8e5e5f04e7d4aaddc/1559047353004/iconfinder_lighthouse_boat_sea_summer_vacation_holidays_3405125.png');
  background-size: contain;
  vertical-align: middle;
  margin-right: 5px;
}
15. Containing image.png

By force of habit, I also like to set the background image to no repeat:

.Header-nav--primary .Header-nav-item:nth-child(1)::before {
  content: '';
  height: 30px;
  width: 30px;
  display: inline-block;
  background: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2cb8e5e5f04e7d4aaddc/1559047353004/iconfinder_lighthouse_boat_sea_summer_vacation_holidays_3405125.png');
  background-size: contain;
  background-repeat: no-repeat;
  vertical-align: middle;
  margin-right: 5px;
}
16. Setting to no repeat.png

And I think I also want my icon a liiiittle bit bigger, so I’ll change the container height and width from 30px to 40px:

.Header-nav--primary .Header-nav-item:nth-child(1)::before {
  content: '';
  height: 40px;
  width: 40px;
  display: inline-block;
  background: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2cb8e5e5f04e7d4aaddc/1559047353004/iconfinder_lighthouse_boat_sea_summer_vacation_holidays_3405125.png');
  background-size: contain;
  background-repeat: no-repeat;
  vertical-align: middle;
  margin-right: 5px;
}
17. Increasing icon size.png

Love it!!

With all of these styles set, we can simply copy/paste our code and switch up the selectors to match our other links with their corresponding icons.

Note: we’ll be cleaning up any code repetition a bit later on

So, moving onto our About link, we can simply change up our nth-child position from 1 to 2 and add in the corresponding background url:

.Header-nav--primary .Header-nav-item:nth-child(2)::before {
  content: '';
  height: 40px;
  width: 40px;
  display: inline-block;
  background: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2dd6f4e1fc1153ed99d9/1559047638802/iconfinder_Nautical_marine_maritime_naval_sea_ocean-12_2755676.png');
  background-size: contain;
  background-repeat: no-repeat;
  vertical-align: middle;
  margin-right: 5px;
}
19. Targeting through nth child.png

As simple as that!

However, what if we switch it up and use the second approach mentioned earlier?

Using a unique attribute as reference

This subtitle pretty much spoiled it but here’s the thing: we need to find something that’s unique for each of our link items (besides position) in order to target them separately.

If we take a look through our Inspect Element window at our About link:

18. Looking for the href attribute.png

We can see it has just the one class that shares with all the other links (.Header-nav-item) and there’s no id, BUT… we can see the href attribute links to a specific page in each case.

So, if you want to make sure your icons always correspond to their link regardless of their position, this is a better approach for you.

Note: if you have folders in your menu, you’ll need to target the folder element through its particular folder class to give it an icon. And if you have more than one folder, you’ll need to go with the first position method.

You can read more about using attribute selectors here, but in this case (since we want to be super specific) we’ll need to use the entire attribute name and value in our selector, instead of the nth-child pseudo-class, like so:

.Header-nav--primary .Header-nav-item[href="/about"]::before {
  
}

And adding in our icon styles we get:

.Header-nav--primary .Header-nav-item[href="/about"]::before {
  content: '';
  height: 40px;
  width: 40px;
  display: inline-block;
  background: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2dd6f4e1fc1153ed99d9/1559047638802/iconfinder_Nautical_marine_maritime_naval_sea_ocean-12_2755676.png');
  background-size: contain;
  background-repeat: no-repeat;
  vertical-align: middle;
  margin-right: 5px;
}
20. Targeting via attribute selector.png

Exactly the same result as before with :nth-child(2)!

So, all that’s left to do here is add the rest of the icons with either approach to the other links:

22. Adding last icon.png

Beautiful!

Adding an icon to each of your menu links, in mobile

If we check what this looks like on tablet (and this may vary depending on your mobile breakpoint), this is what we get:

23. Checking in tablets.png

Our icons stay side by side with our links so it’s all good!

But then when we hit the mobile navigation…

24. Checking in phone screens.png

We don’t see them anymore.

Let’s fix that!

We have to find out what’s the class for our mobile menu links:

25. Looking for link class name.png
26. Checking inspect element up close.png

It’s called .Mobile-overlay-nav-item, great!

And then, what’s the parent of this primary nav called (in case we add a secondary navigation later on):

27. Finding parent container.png

It’s .Mobile-overlay-nav—primary

Alrighty! So, since we want the exact same styles for our icons (or at least I do), instead of copy/pasting everything again, we can simply group selectors under their corresponding snippets.

For example, this what the desktop and mobile selector would look like grouped for the Home menu item:

.Header-nav--primary .Header-nav-item:nth-child(1)::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/"]::before {
  
}

And here’s what the code for all the 4 icons (using both methods and for both desktop and mobile nav) would look like:

/*CONTACT LINK*/
.Header-nav--primary .Header-nav-item[href="/contact"]::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/contact"]::before {
  content: '';
  height: 40px;
  width: 40px;
  display: inline-block;
  background: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2e72eb39314501edd46c/1559047794068/iconfinder_Nautical_marine_maritime_naval_sea_ocean-08_2755680.png');
  background-size: contain;
  background-repeat: no-repeat;
  vertical-align: middle;
  margin-right: 5px;
}

/*SERVICES LINK*/
.Header-nav--primary .Header-nav-item[href="/services"]::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/services"]::before {
  content: '';
  height: 40px;
  width: 40px;
  display: inline-block;
  background: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2e44ec212d2f679fbda5/1559047748873/iconfinder_Nautical_marine_maritime_naval_sea_ocean-28_2755660.png');
  background-size: contain;
  background-repeat: no-repeat;
  vertical-align: middle;
  margin-right: 5px;
}

/*ABOUT LINK*/
.Header-nav--primary .Header-nav-item[href="/about"]::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/about"]::before {
  content: '';
  height: 40px;
  width: 40px;
  display: inline-block;
  background: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2dd6f4e1fc1153ed99d9/1559047638802/iconfinder_Nautical_marine_maritime_naval_sea_ocean-12_2755676.png');
  background-size: contain;
  background-repeat: no-repeat;
  vertical-align: middle;
  margin-right: 5px;
}

/*HOME LINK*/
.Header-nav--primary .Header-nav-item:nth-child(1)::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/"]::before {
  content: '';
  height: 40px;
  width: 40px;
  display: inline-block;
  background: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2cb8e5e5f04e7d4aaddc/1559047353004/iconfinder_lighthouse_boat_sea_summer_vacation_holidays_3405125.png');
  background-size: contain;
  background-repeat: no-repeat;
  vertical-align: middle;
  margin-right: 5px;
}
30. Adding the rest of the links.png

Cool, right?

Now we have nav icons on mobile too!

However, as I mentioned earlier we can clean up the code to avoid so much repetition.

What I’ll do is set all the common pseudo-element styles for ALL links of both desktop and mobile menu in ONE snippet (i.e. ignoring both the position and the href attribute and just targeting the general class shared by all), and then use the specific selectors for each one of the links (position or attribute, in this case it doesn’t matter which one) to apply the corresponding background.

Note: I’ve switched background to background-image because the background shorthand would override the other background properties (size and repeat) set in the basic styles snippet.

/*BASIC STYLES FOR ALL LINKS*/
.Header-nav--primary .Header-nav-item::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item::before {
  content: '';
  height: 40px;
  width: 40px;
  display: inline-block;
  background-size: contain;
  background-repeat: no-repeat;
  vertical-align: middle;
  margin-right: 5px;
}

/*CONTACT LINK*/
.Header-nav--primary .Header-nav-item[href="/contact"]::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/contact"]::before {
  background-image: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2e72eb39314501edd46c/1559047794068/iconfinder_Nautical_marine_maritime_naval_sea_ocean-08_2755680.png');
}

/*SERVICES LINK*/
.Header-nav--primary .Header-nav-item[href="/services"]::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/services"]::before {
  background-image: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2e44ec212d2f679fbda5/1559047748873/iconfinder_Nautical_marine_maritime_naval_sea_ocean-28_2755660.png');
}

/*ABOUT LINK*/
.Header-nav--primary .Header-nav-item[href="/about"]::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/about"]::before {
  background-image: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2dd6f4e1fc1153ed99d9/1559047638802/iconfinder_Nautical_marine_maritime_naval_sea_ocean-12_2755676.png');
}

/*HOME LINK*/
.Header-nav--primary .Header-nav-item:nth-child(1)::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/"]::before {
  background-image: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2cb8e5e5f04e7d4aaddc/1559047353004/iconfinder_lighthouse_boat_sea_summer_vacation_holidays_3405125.png');
}

And there you have it!

This is how you can use CSS to add icons to your navigation items, for both desktop and mobile in Squarespace.

I hope you liked this fun tutorial!

Until next time,

B.

 

Full code

/*BASIC STYLES FOR ALL LINKS*/
.Header-nav--primary .Header-nav-item::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item::before {
  content: '';
  height: 40px;
  width: 40px;
  display: inline-block;
  background-size: contain;
  background-repeat: no-repeat;
  vertical-align: middle;
  margin-right: 5px;
}

/*CONTACT LINK*/
.Header-nav--primary .Header-nav-item[href="/contact"]::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/contact"]::before {
  background-image: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2e72eb39314501edd46c/1559047794068/iconfinder_Nautical_marine_maritime_naval_sea_ocean-08_2755680.png');
}

/*SERVICES LINK*/
.Header-nav--primary .Header-nav-item[href="/services"]::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/services"]::before {
  background-image: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2e44ec212d2f679fbda5/1559047748873/iconfinder_Nautical_marine_maritime_naval_sea_ocean-28_2755660.png');
}

/*ABOUT LINK*/
.Header-nav--primary .Header-nav-item[href="/about"]::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/about"]::before {
  background-image: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2dd6f4e1fc1153ed99d9/1559047638802/iconfinder_Nautical_marine_maritime_naval_sea_ocean-12_2755676.png');
}

/*HOME LINK*/
.Header-nav--primary .Header-nav-item:nth-child(1)::before,
.Mobile-overlay-nav--primary .Mobile-overlay-nav-item[href="/"]::before {
  background-image: url('https://static1.squarespace.com/static/5ced253de3cf090001e8017e/t/5ced2cb8e5e5f04e7d4aaddc/1559047353004/iconfinder_lighthouse_boat_sea_summer_vacation_holidays_3405125.png');
}