How to add images to WordPress custom menu links

My blog is a WordPress blog. I think it is a good platform for a blog, but occasionally I will find small shortcomings. One such shortcoming is no obvious way to include an image in a custom menu link. Let me explain: In WordPress, you can create a “custom menu”, which can then be included in various places on your blog. For example, I use a custom menu for my main navigation menu (the one at the top of this blog that has the links “Blog Home”, “About Me”, “Blog Rationale” and “Blog RSS Feed”). The problem is that when you create a menu and add a custom link to the menu (see reference figure below), it only shows options for a link URL and a text label (no option for adding an image).

No image options when adding a custom link

You can see from my navigation menu above (and the cropped image below), though, that there must be a way to add an image because I have an RSS icon included with the “Blog RSS Feed” link.

Menu example - the link has an image and text

Adding an image is relatively simple, you just have to either stumble across a blog like this one that explains it, or know a bit about web design. Luckily, I have some background in web design, had a hunch about what would work for adding images to the WordPress links, and indeed my hunch was correct. The instructions below describe how to add an image to a custom link.

Before creating a link in a custom menu, first you have to create a custom menu. Do this in the WordPress admin page by clicking on “Appearance” and then “Menus”. From there you can create a new menu by clicking on the tab with the “+” sign, type in a name for the menu, and then click the “Create Menu” button.

Click image to enlarge

After that it will allow you to add all sorts of items to your custom menu. It allows you to add predefined links to pages, themes, categories and custom links. As mentioned before, the custom links only show text options, but you can add custom code in the “Label” field to make it show whatever you want. However, the text field is so short that it makes it difficult to see what code you have entered in there, so I would recommend typing the code into a text editor like Notepad or Vim and then copying/pasting it into the field. Here is the code I entered into the “Label” field:

<div style="background-image: url('/images/16px-Feed-icon.png'); background-repeat: no-repeat; display: inline; margin: 0; padding: 0 0 0 20px;"> Blog RSS Feed</div>

Click image to enlarge

After pasting in the code (I’ll explain the code in a bit…), click the “Add to Menu” button. The result looks like the figure below. It is misleading because it looks like it just copied the text directly over just as you typed it in. However, when you actually use the menu somewhere in your blog it will show the image and text correctly, instead of just regurgitating the code.

Click image to enlarge

You probably don’t want to add the code that I used, because I put in exactly what I wanted for my own blog and you will want something else that is customized just for your own blog. So let me explain what the code all means so that you can customize it however you want. First, let me show the same code, but shown in an easier to read format:

<div style="
    background-image: url('/images/16px-Feed-icon.png');
    background-repeat: no-repeat;
    display: inline;
    margin: 0;
    padding: 0 0 0 20px;
"> Blog RSS Feed</div>

First, note that there is a “<div></div>” tag set around the text “Blog RSS Feed”. This basically gives us a small, customizable block around the text label that we can then play with (i.e., customize with an image). We can modify the div block by using the “style=""” attribute (within the opening <div> tag as shown above).

The line “background-image: url('/images/16px-Feed-icon.png');” specifies what image file you want to use. This the first thing you need to change – make it point to the path of your image file.

The line “background-repeat: no-repeat;” says that we want the image to show once, without being a repeating background. You should leave this as-is unless you want a background that repeats horizontally, vertically, or both.

The line “display: inline;” means that it will render the link in the div tags inline in its context rather than putting it on a new line all by itself (which would look really terrible).

The line “margin: 0;” says that we don’t want the div block to have any extra spacing around it, other than what already will exist for for the content in that location.

The line “padding: 0 0 0 20px;” is similar to the “margin” line above, except that we expanded it out to having four values. The values define some extra space that we want in the div block in the directions of above, right, below, and left respectively. By saying we want 20px (20 pixels) of space to the left, I am specifying enough space for the image before the text portion of the label begins. This value of 20px needs to be updated to match (or be slightly larger than) the width of the image that you are using. For example, if your image is 50 pixels wide, then put something like 50px or 55px.

After you’re all done and have clicked the “Add to Menu” button, click the “Save Menu” button to save the link in the menu. If you want to use this new menu as your main navigation menu (like I am), then select the menu you created from the drop-down menu in the “Theme Locations” box and then click “Save”.

That’s all – easy!

126 thoughts on “How to add images to WordPress custom menu links”

  1. Hey your post was very useful but I just wanted to help anyone that just wanted an image but no text, it is the same idea but you can just stick your image source into the label and be done with it. so like and it works like a charm.

    I knew that there had to be a way but this was the only place that I could find an answer so thanks again…

    1. well it cut the snippet of code out that I put but it would be img src=”” in brackets…

          1. Thanks so much for this awesome tutorial! I’m also trying to just have icons with links but no text. But when I try to input the img src code, the code disappears every time I save the menu. Am I doing something wrong? Is it because I’m trying to do it in the Secondary Menu??

          2. If the code disappears whenever you enter it, then I am guessing that you are using WordPress’s site to run you blog and domain name. They do this to keep people from entering malicious code that could harm their servers.

            An alternate way to do this is by specifying a “class” for the menu you are creating (you might have to click on “Screen Options” -> “CSS Classes” at the top of the screen for this to show up), and then entering your custom CSS for that class in the theme’s CSS file to specify a width, height, and background image.

    2. This is exactly what I was looking for. I wanted all of my menu buttons to be images – with no text next to them.

      I put this into the ‘label’ – and the actual size of my uploaded image was 16 px (h) x 64 px (w)

      The image came out quite large. Any ideas what I did wrong?

      I’m a total novice and really appreciate these blogs for help. Thanks guys!

      1. took my code out too – whoops. See, I really am a novice πŸ™‚

        it was this – with brackets:
        img src=””

      2. Yes, it looks like the problem is that you included the menu in the “branding” block of your HTML code. If you look at your CSS you will see that your image is getting set to the same size as your header image (550w x 159h) because they both fall into the CSS “#branding img” rule in your CSS file “style.css”.

        Your CSS file is correct. Your HTML is incorrect. It looks like when you manually edited your WordPress theme files you accidentally included the menu in the “branding” block instead of leaving it right after the “branding” block.

        Clear as mud? I can go into more detail, just let me know…

        1. Thanks so much for your help!
          I see what your talking about. Do you mind explaining how I would go about editing it so that my navigation bar images are not getting sized like the #branding img?

          What file would I edit if the CSS is correct?

      3. The other way around this would be to specify the style for the image directly in the tag like this:

        <img src="" style="width: 64px; height: 16px; padding: 0; margin: 0;">

        1. You. are. awesome.
          thank you a million times! You’d think I’d be able to pick up on something that easy… but alas!

  2. Just wanted to say thanks. I have built my website from scratch and the only way I learn is by researching on the net. The problem I have found is that most people who post “how to” info seem to assume that people already fully understand html and css coding so it is very hard to understand what they have written.

    After finding your post I was able to impliment what I wanted within 10 minutes. Thanks for making it easy to understand!

    1. I completely understand what you mean. You will always find what you said to be true, even if you have already become an “expert” in that area. I would add my own 2¢ to the oft-quoted thought that “there is always someone smarter than you [but you’d never guess it because nobody understands them]”.

    1. You have a few typos.

      • First of all, your background image URL is incorrect. You have ‘/images/bar1.png’, which is wrong. Change it to ‘’.
      • Also, you have a typo: change “backgroung-image” to “background-image”.
      • You are also missing a semi-colon (“;”) after “height: 30px”.

      Try that. By the way, that is a very cool header image, is that built in with the theme, or is that your own image?

      1. Heurika!

        Thanks – seem like simple things, but I changed the code a 1000 times yesterday in order to get it to work. In the end I problably added mistakes.

        Never the less – it works now, Thanks Mike!
        Now I just have to expirement with getting the image to just the size I want. I am trying to avoid having to create a seperate CSS style for each item.

        The header image is my own – thanks for mentioning it. I am still working on perfecting it concidering to add a punch line in the corner or something.

  3. Thanks so much for posting this, it has allowed me to do most of what I wanted to do with the Art Gallery for school.

    However, is there anyway to make the custom menu space itself wider, so I can get the whole image in?

    1. Yes, you can make it wider. Normally the menu item will expand its width automatically to match the length of the text. In your case, though, it sounds like you are trying to use an image that is wider than the text (or you are using only an image without any additional text) so it isn’t automatically expanding for you.

      You can make the menu space wider by adding the parameter "width: 100px;" to the style attribute, except replace "100px" with the width of your picture. So, for example, if your image is 55 pixels wide, then your code would look something like this:
      <div style="
          background-image: url('/images/16px-Feed-icon.png');
          background-repeat: no-repeat;
          display: inline;
          margin: 0;
          padding: 0 0 0 20px;
          width: 55px;
      "> Blog RSS Feed</div>

      1. Lara, I’m afraid my response to your question was a bit incorrect. With the “display: inline” parameter being used, adding the “width: 55px” parameter will not have any effect. Instead, you should increase the padding from 20px to whatever you want the width of the box to be. This assumes that you aren’t using any text in your menu button, but instead that you are using only an image for the button. If this is indeed what you are doing, then you should use code like this:
        <div style="
            background-image: url('/images/16px-Feed-icon.png');
            background-repeat: no-repeat;
            display: inline;
            margin: 0;
            padding: 0 0 0 55px;

        where the “55px” now appears as part of the “padding” attribute.

  4. Hi Mike, thanks for this tutorial, much appreciated.

    I have got an issue, and I though between your code and the following, you could come up with an idea?

    Basically, if I only want the icon to how up (not text), using the following code, as you suggested:
    I have to reduce the image size dramatically, to make it fit in the menu bar, then the picture looks too small.

    On the other hand, with the other code, in the link above, you can resize the picture with the values, and the great thing is that the menu bar doesn’t move/increase in height.

    The problem is that the code adds the text as well as the picture.

    1. I’m guessing you tried to add some code there in your comment but then WordPress removed it when you submitted your comment. To include code in your comment, replace the "<" characters with "&lt;" and the ">" characters with "&gt;".

      1. Thank you, the code I tried to paste is the following:
        < img src=”” style=”width: 64px; height: 16px; padding: 0; margin: 0;”>

        An the other code, is in the link showing on my previous post.

        1. I think I understand what you are trying to do. It sounds like you want to do about the same thing that Lara (a few comments above) was trying to do. However, I gave her some incorrect info.

          What you need to do is use the image as a background image (like in my original post above and in my response to Lara above). But instead of trying to increase the “width” to some bigger value, you should instead increase the right-side or left-side padding to a larger number. For example, if you want your image to be 55 pixels wide, and you don’t want to have any text in the menu button, then you could use some code like this:
          <div style="
              background-image: url('');
              background-repeat: no-repeat;
              display: inline;
              margin: 0;
              padding: 0 0 0 55px;

          Note how the “padding” attribute now has “55px” in it. Those four values “0 0 0 55px” represent how much padding you want on top, right, bottom and left, respectively. So the code above adds 55px of padding on the left.

  5. Hi Mike, it’s the website in my details. I usually do the test late when it’s quiet, then I always restore everything quickly.

    I found another great article here, that should do it, more than I needed, but actually, really good to know the possibilities:

    So, all I have to do is play with it now. I think they forgot the “background-repeat:no-repeat !important;” though.

    1. Yes, that looks like a good resource for what you are trying to do. I think the key to what they are showing is the "background-position: ##px ##px;" style attribute, where the ## can be a positive or negative number used to position the background image. You might not even have to change what you already have by too much if you try just adding the background-position attribute to the style.

  6. Yes, I have actually learned something interesting with this tutorial as well, it’s great to use 1 sprite/image instead of multiple ones.
    However, sadly, this is not going to work for me, because it gets messy with sub pages…, so I won’t use it for this purpose, but for single links it’s pretty good. It’s ok though, I am not too worry about this at the minute.

    I have an other question in case you have an idea;
    What would be the best way to add a text over a picture (the picture in question would be the “feature image” showing as an excerpt) and the text would be actually a short code; so far, I came up with the following:
    div#custom_x {
    position: relative;
    float: left;
    height: auto;
    width: auto;
    max-height: 1px;
    left: 1px;
    bottom: 25px;

    The reason for the “max-height: 1px;” (trying to fix a problem) is because the text/short code, creates a margin below the picture, which I don’t want, but the text/short code still show up with this setting.
    It seems to work, but I am not sure if this is correct way though.

    The setting for the picture/post thumbnail is:
    float: relative;
    border: 0;
    padding: 0;
    background: none;

    Again, I don’t know what I am doing, I did “float: relative;” as instead of left, which was the default setting, because the text/short code would show up at the right, and I want the text to be right underneath the picture.

    As I said, it’s “working”, but I won’t use it unless I am 100% sure that the styling is correct.

    1. Instead of doing “float: relative” for the picture, you should do “float: none” which will turn off the floating. Using relative in this attribute is incorrect.

      Other than that, as long as the CSS is generating the correct appearance then you are probably OK. However, make sure you try view the page on different web browsers since they will interpret CSS and div behaviors differently. Especially when using the “max-height” attribute, since some browsers do not support that attribute at all.

      I don’t completely understand what layout you are describing with the picture and the short code. Are you saying that you want the text to be directly beneath the picture, or are you saying that you want the picture to be shown behind the text, with the text near the bottom of the picture?

  7. Hello,

    Just wanted to let you know that your tutorial is awesome. I used your instructions to add little FB and Twitter icons to his links. Thank you so much. His site is: if you want to take a look.

    What I really loved about this is that it worked the first time, without having to figure anything else out. You wrote it so well that I literally cut and pasted your code, changed the image src location and the link text. Brilliant!!

  8. Have you tried adding an indent to the CSS in the ? Try adding the following line and see how that works:

    text-indent: -9999px;

    If all goes well, the text won’t be seen on the screen while the image remains, and search engines like Google will still be able to read the link.

    1. That’s a good suggestion, especially for keeping the text present like you said. That could arguably be replaced with making sure you include the "title" attribute in the <a> and <img> tags and include the "alt" attribute in the <img> tag. Good suggestion!

  9. This is one of those moments that I’ll say “why I didn’t thought about that?”, this is cool considering how simple it is.
    Btw, is there any alternative? Like what if the client wanted to add a new navigation, and the image will automatically included on the nav?

  10. Hello!

    What a great tutorial! I have been trying to figure this out for about a few days and finally just hardcoded it in there. I would love to make it a dynamic list. I have followed your instructions and read through every comment and still can’t get it to work. My header is set-up for 2 custom menus. I disabled the second one and just hard-coded the menu in place. I am adding link of what I want to look like. It’s the nav in white. If I just add html code in the label field will it find style.css or do the styles need to be in the label input as well. Would appreciate any pointers.
    Thanks!! πŸ™‚

  11. Mike I did it!!! I am not totally sure what I did different but I got it to work!! I am so thankful you took the time to share this tutorial.
    S πŸ™‚

Leave a Reply

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