Custom Dropdown Arrow With Pure CSS (Simple Example)

Welcome to a tutorial on how to create a custom dropdown arrow using pure CSS and HTML. Yes, we can pretty much do any customization with modern HTML and CSS. But strangely, there is no straightforward way to customize a dropdown arrow in pure CSS.

To create a custom dropdown arrow:

  1. Wrap the select box – <div class="sel"><select><option>Demo</option></select></div>
  2. Hide the default arrow – .sel select { apperance: none }
  3. Create a custom arrow with HTML symbol – .sel::after { content: "\25b6" }
  4. Position the custom arrow – .sel { position: relative } .sel::after { position: absolute; top: 0; right: 0 }

That covers the basic mechanics, but let us walk through a detailed example in this guide – Read on!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

TLDR – QUICK SLIDES

[web_stories_embed url=”https://code-boxx.com/web-stories/customized-dropdown-arrow-with-css/” title=”Customized Dropdown Arrow With CSS” poster=”https://code-boxx.com/wp-content/uploads/2022/03/STORY-HTML-20230505.webp” width=”360″ height=”600″ align=”center”]

Fullscreen Mode – Click Here

 

 

TABLE OF CONTENTS

 

DOWNLOAD & DEMO

Firstly, here is the download link to the example code as promised.

 

QUICK NOTES

If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

EXAMPLE CODE DOWNLOAD

Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

 

THE DEMO

 

 

PURE CSS CUSTOM DROPDOWN

All right, let us now dive into the example of how to customize a dropdown using pure CSS only.

 

PART 1) HTML – WRAP THE SELECT BOX

cselect.html
<div class="sel"><select>
  <option>Good Boy Doge</option>
  <option>Evil Cate</option>
  <option>Sneezing Panda</option>
  <option>Confession Bear</option>
  <option>Fabulous Llama</option>
</select></div>

No sweat. All we need in the HTML is to wrap a normal <select> within a <div> wrapper.

 

 

PART 2) CUSTOM HTML ARROW SYMBOL

cselect.css
/* (A) BASICS - HIDE DEFAULT + SHOW CUSTOM ARROW */
.sel select { appearance: none; }
.sel::after { content: "\25b6"; }
 
/* (B) DIMENSIONS */
/* (B1) WRAPPER - OPTIONAL */
.sel { max-width: 400px; margin: 10px; }
 
/* (B2) "EXPAND" SELECT BOX */
.sel select {
  width: 100%; padding: 10px;
  color: #333;
  border: 1px solid #cfcfcf;
}

Now, here comes the irritating part – CSS does not have a property to set the dropdown arrow, we have to do it through “alternative means”.

  • (A1) Hide the default dropdown arrow using appearance: none.
  • (A1) Use an HTML symbol to create our own custom arrow – .sel::after { content: "\CODE"; }. I will leave a link to a list of HTML symbols in the extras section below.
  • (B) “Expand” the <select> box with width: 100%, and make it fill up the <div> container.

 

PART 3) POSITIONING THE ARROW

cselect.css
/* (C) POSITION CUSTOM ARROW */
/* (C1) REQUIRED FOR ABSOLUTE POSITION BELOW */
.sel { position: relative; }

/* (C2) DEFAULT - ARROW ON RIGHT SIDE */
.sel::after {
  position: absolute;
  top: 50%; right: 10px;
  transform: translateY(-50%);
}
 
/* (C3) ARROW ON LEFT SIDE */
.left.sel::after { left: 10px; right: auto; }
.left.sel select { padding-left: 30px; }

To properly position the arrow:

  • (C1) It is necessary to set the <div> container to position: relative.
  • (C2) Setting position: absolute; top: 50%; right: N will “push” the arrow to the right side of the <div> container.
  •  (C2) Take note, top: 50% will not “accurately vertical center” the arrow. It is necessary to add translateY(-50%) to do that.
  • (C3) If you want the arrow to be on the left side, just set left: Npx; right: auto.

 

 

EXTRA) COSMETICS

cselect.css
/* (D) COSMETICS */
/* (D1) CUSTOM ARROW IS ESSENTIALLY TEXT! */
.sel::after { font-size: 16px; color: #aaa; }
 
/* (D2) ROTATE ARROW ON HOVER */
.sel::after { transition: all 0.3s; }
.sel:hover::after {
  transform: translateY(-50%) rotate(90deg);
  color: #ff1212;
}

Finally, some optional cosmetics.

  • (D1) The HTML arrow symbol is still text. We can apply color and font size to it.
  • (D2) Using CSS transition and rotate, we can easily add a “rotate on mouse hover” animation.

 

EXTRA BITS & LINKS

That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.

 

COMPATIBILITY CHECKS

This example will work on all “Grade A” modern browsers.

 

CAN WE CUSTOMIZE THE DROPDOWN OPTIONS?

  • No, not exactly. Some CSS properties do work on <option>, but every browser renders the <select><option> differently.
  • On a desktop, the selectable options will be below the box.
  • But on mobile, it will probably become a popup instead.

The only way to create a “fully customized dropdown box” is to “entirely customize it”, and “make it from scratch”.

 

LINKS & REFERENCES

 

TUTORIAL VIDEO

 

INFOGRAPHIC CHEAT SHEET

Custom CSS Dropdown (click to enlarge)

 

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

5 thoughts on “Custom Dropdown Arrow With Pure CSS (Simple Example)”

  1. Hi
    I want to add a three dot loading indicator for select icon while options are being loaded. Can you guide me?

    1. 1) Study AJAX
      2) While loading – Disable dropdown and show “now loading”
      3) On loaded – Enable dropdown and show “dropdown arrow”

      Otherwise, I will take this as a request for a new tutorial. Good luck.

      https://code-boxx.com/faq/#help “Requests for new features and tutorials may be considered, but will not be immediately answered”

  2. Hi
    Thank you for this quick and easy method. It helped me and one thing that I added was the z-index so clicking the arrow “seem” to activate the dropdown:
    simply added :
    .cselect select { z-index: 2; }
    .cselect::after { z-index: 1; }
    Thanks again!

  3. Hello,
    Would it be possible to add support for a scrollbar if there are many items in the list?

    1. No, there’s no CSS to directly control it. Also on mobile browsers, this will probably be rendered differently as a scrollable popup list.

Comments are closed.