200

I have a select list of genders.

Code:

<select>
<option>male</option>
<option>female</option>
<option>others</option>
</select>  

I want to use an image in drop down list as drop-down-icon.jpeg.

I want to add a button in place of drop down icon.

How to do that?

Mayur
  • 2,835
  • 6
  • 27
  • 27
  • 9
    duplicate of [Image in SELECT element](http://stackoverflow.com/questions/1697996/image-in-select-element) and [How can I put an image into select?](http://stackoverflow.com/questions/2524953/how-can-i-put-an-image-into-select). http://stackoverflow.com/search?q=html+select+image. – Andy E Jun 03 '10 at 12:53
  • 5
    as a general solution: if you can, get your icons together as SVGs, import them into a font of your choice into the personal Unicode range, use that font in your ` –  Oct 28 '17 at 18:02

15 Answers15

203

In Firefox you can just add background image to option:

<select>
  <option style="background-image:url(male.png);">male</option>
  <option style="background-image:url(female.png);">female</option>
  <option style="background-image:url(others.png);">others</option>
</select> 

Better yet, you can separate HTML and CSS like that

HTML

<select id="gender">
  <option>male</option>
  <option>female</option>
  <option>others</option>
</select>  

CSS

select#gender option[value="male"]   { background-image:url(male.png);   }
select#gender option[value="female"] { background-image:url(female.png); }
select#gender option[value="others"] { background-image:url(others.png); }

In other browsers the only way of doing that would be using some JS widget library, like for example jQuery UI, e.g. using Selectable.

From jQuery UI 1.11, Selectmenu widget is available, which is very close to what you want.

nhahtdh
  • 55,989
  • 15
  • 126
  • 162
vartec
  • 131,205
  • 36
  • 218
  • 244
43

With countries, languages or currency you may use emojis.

Works with pretty much every browser/OS that supports the use of emojis.

select {
 height: 50px;
 line-height: 50px;
 font-size: 12pt;
}
<select name="countries">
    <option value="NL">&emsp;Netherlands</option>
    <option value="DE">&emsp;Germany</option>
    <option value="FR">&emsp;France</option>
    <option value="ES">&emsp;Spain</option>
</select>

<br /><br />

<select name="currency">
    <option value="EUR">&emsp;€&emsp;EUR&emsp;</option>
    <option value="GBP">&emsp;£&emsp;GBP&emsp;</option>
    <option value="USD">&emsp;$&emsp;USD&emsp;</option>
    <option value="YEN">&emsp;¥&emsp;YEN&emsp;</option>
</select>
Tim
  • 2,805
  • 25
  • 21
  • 19
    _"Works with pretty much every browser/OS that supports the use of emojis"_ ....except that Windows does not support emoji flags. – skomisa Feb 13 '19 at 19:40
  • 3
    ...and neither does Google Chrome, even outside Windows :( – Piskvor left the building Oct 21 '19 at 12:24
  • 2
    Three and a half years later and this is still not a solution for displaying emoji flags on Windows, with the notable exception of Firefox. So unless you are using Firefox on Windows, the flags in the _countries_ list above will be rendered with their associated regional indicator symbols instead. For example, the entry for _France_ will render _FR_ instead of the French flag, etc. – skomisa Apr 03 '22 at 18:31
  • 1
    This breaks the keyboard navigation in the case when you type the first letters of the value that you want to select (it looks like this standard behaviour is based on the option text instead of the option value attribute BTW) – Big_Boulard Dec 08 '22 at 12:04
32

You can use iconselect.js; Icon/image select (combobox, dropdown)

Demo and download; http://bug7a.github.io/iconselect.js/

enter image description here

HTML usage;

<div id="my-icon-select"></div>

Javascript usage;

    var iconSelect;

    window.onload = function(){

        iconSelect = new IconSelect("my-icon-select");

        var icons = [];
        icons.push({'iconFilePath':'images/icons/1.png', 'iconValue':'1'});
        icons.push({'iconFilePath':'images/icons/2.png', 'iconValue':'2'});
        icons.push({'iconFilePath':'images/icons/3.png', 'iconValue':'3'});

        iconSelect.refresh(icons);

    };
bugra ozden
  • 457
  • 5
  • 7
32

My solution is to use Font Awesome and then add library icons as text, using the unicode in HTML directly.

You just need the Unicode value for whatever icon you want, and they are all found here: Font Awesome full list of icons, including unicode

image showing where to click to copy the unicode for a given icon

Here is an example state filter:

<select name='state' style='height: 45px; font-family:Arial, Font Awesome;'>
  <option value=''>&#xf039; &nbsp; All States</option>
  <option value='enabled' style='color:green;'>&#xf00c; &nbsp; Enabled</option>
  <option value='paused' style='color:orange;'>&#xf04c; &nbsp; Paused</option>
  <option value='archived' style='color:red;'>&#xf023; &nbsp; Archived</option>
</select>

Note the font-family:Arial, FontAwesome; is required to be assigned in style for select like given in the example.

Trece
  • 37
  • 6
Tarik
  • 4,270
  • 38
  • 35
  • 1
    this solution doens't work on the option, only when selected (pen: https://codepen.io/wtfgraciano/pen/YMwWqK) – graciano Apr 03 '19 at 20:31
  • It does work but the feature is browser dependent. It works well on Chrome in Windows for example. – Tarik Apr 04 '19 at 05:30
  • What do you mean add library images as text ? Sorry I don't quite follow, do you mind explaining ? – RyanN1220 Apr 30 '19 at 10:09
  • 1
    @RyanN1220 Fontawesome is a library has mini images. And each image has a corresponding unicode text that you can apply. See the link in the answer for the text code. (https://fontawesome.com/cheatsheet?from=io#social-buttons) Nothign special, just follow the example in the answer and you should be good to go. – Tarik Apr 30 '19 at 21:32
28

You already have several answers that suggest using JavaScript/jQuery. I am going to add an alternative that only uses HTML and CSS without any JS.

The basic idea is to use a set of radio buttons and labels (that will activate/deactivate the radio buttons), and with CSS control that only the label associated to the selected radio button will be displayed. If you want to allow selecting multiple values, you could achieve it by using checkboxes instead of radio buttons.

Here is an example. The code may be a bit messier (specially compared to the other solutions):

.select-sim {
  width:200px;
  height:22px;
  line-height:22px;
  vertical-align:middle;
  position:relative;
  background:white;
  border:1px solid #ccc;
  overflow:hidden;
}

.select-sim::after {
  content:"▼";
  font-size:0.5em;
  font-family:arial;
  position:absolute;
  top:50%;
  right:5px;
  transform:translate(0, -50%);
}

.select-sim:hover::after {
  content:"";
}

.select-sim:hover {
  overflow:visible;
}

.select-sim:hover .options .option label {
  display:inline-block;
}

.select-sim:hover .options {
  background:white;
  border:1px solid #ccc;
  position:absolute;
  top:-1px;
  left:-1px;
  width:100%;
  height:88px;
  overflow-y:scroll;
}

.select-sim .options .option {
  overflow:hidden;
}

.select-sim:hover .options .option {
  height:22px;
  overflow:hidden;
}

.select-sim .options .option img {
  vertical-align:middle;
}

.select-sim .options .option label {
  display:none;
}

.select-sim .options .option input {
  width:0;
  height:0;
  overflow:hidden;
  margin:0;
  padding:0;
  float:left;
  display:inline-block;
  /* fix specific for Firefox */
  position: absolute;
  left: -10000px;
}

.select-sim .options .option input:checked + label {
  display:block;
  width:100%;
}

.select-sim:hover .options .option input + label {
  display:block;
}

.select-sim:hover .options .option input:checked + label {
  background:#fffff0;
}
<div class="select-sim" id="select-color">
  <div class="options">
    <div class="option">
      <input type="radio" name="color" value="" id="color-" checked />
      <label for="color-">
        <img src="http://placehold.it/22/ffffff/ffffff" alt="" /> Select an option
      </label>
    </div>
    <div class="option">
      <input type="radio" name="color" value="red" id="color-red" />
      <label for="color-red">
        <img src="http://placehold.it/22/ff0000/ffffff" alt="" /> Red
      </label>
    </div>
    <div class="option">
      <input type="radio" name="color" value="green" id="color-green" />
      <label for="color-green">
        <img src="http://placehold.it/22/00ff00/ffffff" alt="" /> Green
      </label>
    </div>
    <div class="option">
      <input type="radio" name="color" value="blue" id="color-blue" />
      <label for="color-blue">
        <img src="http://placehold.it/22/0000ff/ffffff" alt="" /> Blue
      </label>
    </div>
    <div class="option">
      <input type="radio" name="color" value="yellow" id="color-yellow" />
      <label for="color-yellow">
        <img src="http://placehold.it/22/ffff00/ffffff" alt="" /> Yellow
      </label>
    </div>
    <div class="option">
      <input type="radio" name="color" value="pink" id="color-pink" />
      <label for="color-pink">
        <img src="http://placehold.it/22/ff00ff/ffffff" alt="" /> Pink
      </label>
    </div>
    <div class="option">
      <input type="radio" name="color" value="turquoise" id="color-turquoise" />
      <label for="color-turquoise">
        <img src="http://placehold.it/22/00ffff/ffffff" alt="" /> Turquoise
      </label>
    </div>
  </div>
</div>
Alvaro Montoro
  • 28,081
  • 7
  • 57
  • 86
  • 9
    Need to move mouse out for it to collapse. Can it be done on click and not mouse hover/ move? Would this work on mobile/ non mouse devices? – tgkprog Jun 03 '18 at 08:06
4

This is using ms-Dropdown : https://github.com/marghoobsuleman/ms-Dropdown

Data resource is json. But you dont need to use json. If you want you can use with css.

Css example : https://github.com/marghoobsuleman/ms-Dropdown/tree/master/examples

Json Example : http://jsfiddle.net/tcibikci/w3rdhj4s/6

HTML

<div id="byjson"></div>

Script

<script>
        var jsonData = [
            {description:'Choos your payment gateway', value:'', text:'Payment Gateway'},
            {image:'https://via.placeholder.com/50', description:'My life. My card...', value:'amex', text:'Amex'},
            {image:'https://via.placeholder.com/50', description:'It pays to Discover...', value:'Discover', text:'Discover'},
            {image:'https://via.placeholder.com/50', title:'For everything else...', description:'For everything else...', value:'Mastercard', text:'Mastercard'},
            {image:'https://via.placeholder.com/50', description:'Sorry not available...', value:'cash', text:'Cash on devlivery', disabled:true},
            {image:'https://via.placeholder.com/50', description:'All you need...', value:'Visa', text:'Visa'},
            {image:'https://via.placeholder.com/50', description:'Pay and get paid...', value:'Paypal', text:'Paypal'}
        ];
        $("#byjson").msDropDown({byJson:{data:jsonData, name:'payments2'}}).data("dd");
    }
</script>
Tolga
  • 147
  • 3
  • 4
3

For those wanting to display an icon, and accepting a "black and white" solution, one possibility is using character entities:

   <select>
      <option>100 &euro;</option>
      <option>89 &pound;</option>
    </select>

By extension, your icons can be stored in a custom font. Here's an example using the font FontAwesome: https://jsfiddle.net/14606fv9/2/ https://jsfiddle.net/14606fv9/2/

One benefit is that it doesn't require any Javascript. However, pay attention that loading the full font doesn't slow down the loading of your page.

Nota bene: The solution of using a background image doesn't seem working anymore in Firefox (at least in version 57 "Quantum"):

<select>
  <option style="background-image:url(euro.png);">100</option>
  <option style="background-image:url(pound.png);">89</option>
</select>
OuzoPower
  • 230
  • 2
  • 11
2

For a two color image, you can use Fontello, and import any custom glyph you want to use. Just make your image in Illustrator, save to SVG, and drop it onto the Fontello site, then download your custom font ready to import. No JavaScript!

BBaysinger
  • 6,614
  • 13
  • 63
  • 132
2

Alvaros JS free answer was a great start for me, and I really tried to get a truly JS-free answer that still delivered all the functionality expected of a Select with images, but sadly nesting forms was the down-fall. I'm posting two solutions here; my main solution that uses 1 line of JavaScript, and a totally JavaScript-free solution that won't work inside another form, but might be useful for nav menus.

Unfortunately there is a bit of repetition in the code, but when you think about what a Select does it makes sense. When you click on an option it copies that text to the selected area, i.e., clicking 1 of 4 options will not change the 4 options, but the top will now repeat the one you clicked. To do this with images would require JavaScript, orrrr... you duplicate the entries.

In my example we have a list of games (Products), which have versions. Each product may also have Expansions, which can also have versions. For each Product we give the user a list of each version if there's more than one, along with an image and version specific text.

<h4>@Model.Name</h4>
@if (Model.Versions.Count == 1)
{
    <div class="rich-select-option-body pl-2">
        <img src="@Model.Versions[0].ImageUrl" alt="">@Model.Versions[0].VersionName (@Model.Versions[0].Year)
    </div>
}
else
{
    <h5>Select the version</h5>
    <div class="rich-select custom-select">
        <div class="rich-select-dropdown">
            @foreach (var version in Model.Versions)
            {
                <div class="rich-select-option">
                    <input type="radio" name="game" id="game-@version.ProductId-@version.VersionId" @if (version == Model.Versions.First()) { @Html.Raw(" checked") ; } />
                    <div class="rich-select-option-body">
                        <label tabindex="-1">
                            <img src="@version.ImageUrl" alt="">@version.VersionName (@version.Year)
                        </label>
                    </div>
                </div>
            }
        </div>
        <input type="checkbox" id="rich-select-dropdown-button" class="rich-select-dropdown-button" />
        <label for="rich-select-dropdown-button"></label>
        <div class="rich-select-options">
            @foreach (var version in Model.Versions)
            {
                <div class="rich-select-option">
                    <div class="rich-select-option-body">
                        <label for="game-@version.ProductId-@version.VersionId" tabindex="-1" onclick="document.getElementById('rich-select-dropdown-button').click();">
                            <img src="@version.ImageUrl" alt=""> @version.VersionName (@version.Year)
                        </label>
                    </div>
                </div>
            }
        </div>
    </div>
}

Using JS for the checkbox deselection we can have multiple instances on a form. Here I've extended to show a list of Expansions, which also have the same logic around versions.

<h5 class="mt-3">Include Expansions?</h5>
@foreach (var expansion in Model.Expansions)
{
    <div class="form-row">
        <div class="custom-control custom-checkbox w-100">
            <input type="checkbox" class="expansion-checkbox custom-control-input" id="exp-@expansion.ProductId">
            <label class="custom-control-label w-100" for="exp-@expansion.ProductId">

                @if (expansion.Versions.Count == 1)
                {
                    <div class="rich-select-option-body pl-2">
                        <img src="@expansion.ImageUrl" />@expansion.Name: @expansion.Versions[0].VersionName (@expansion.Versions[0].Year)
                    </div>
                }
                else
                {
                    <div class="rich-select custom-select">
                        <div class="rich-select-dropdown">
                            @foreach (var version in expansion.Versions)
                            {
                                <div class="rich-select-option">
                                    <input type="radio" name="exp-@version.ProductId" id="exp-@version.ProductId-@version.VersionId" @if (version == expansion.Versions.First()) { @Html.Raw(" checked") ; } />
                                    <div class="rich-select-option-body">
                                        <label tabindex="-1">
                                            <img src="@version.ImageUrl" alt="">@expansion.Name: @version.VersionName (@version.Year)
                                        </label>
                                    </div>
                                </div>
                            }
                        </div>

                        <input type="checkbox" id="rich-select-dropdown-button-@expansion.ProductId" class="rich-select-dropdown-button" />
                        <label for="rich-select-dropdown-button-@expansion.ProductId"></label>
                        <div class="rich-select-options">
                            @foreach (var version in expansion.Versions)
                            {
                                <div class="rich-select-option">
                                    <div class="rich-select-option-body">
                                        <label for="exp-@version.ProductId-@version.VersionId" tabindex="-1" onclick="document.getElementById('rich-select-dropdown-button-@expansion.ProductId').click();">
                                            <img src="@version.ImageUrl" alt="">@expansion.Name: @version.VersionName (@version.Year)
                                        </label>
                                    </div>
                                </div>
                            }
                        </div>
                    </div>
                }
            </label>
        </div>
    </div>

Of course this requires a fair bit of CSS, which I've only included in this JSFiddle to reduce the size of this already massive answer. I've used Bootstrap 4 to reduce the amount needed, and also to allow it to fit in with other Bootstrap controls and any site customisations that have been made.

The images are set to 75px, but this can easily be changed in 5 lines in .rich-select and .rich-select-option-body img

Red
  • 3,030
  • 3
  • 22
  • 39
  • 1
    Sadly I am unable to spot your "totally JavaScript-free solution" somehow. BTW: `onclick` cannot be used when CSP denies inline JS (which should be the default but isn't) to protect against one type of [XSS protection](https://developer.mozilla.org/en-US/docs/Web/Security/Types_of_attacks#Cross-site_scripting_XSS). – Tino Oct 18 '20 at 12:32
1

I got the same issue. My solution was a foreach of radio buttons, with the image at the right of it. Since you can only choose a single option at radio, it works (like) a select.

Worked well for me.

Luan Persini
  • 63
  • 1
  • 4
1

I was struggling with the same problem: how to create a language selector with flags. I came up with a :ḧover solution without javascript. It does involve some server-side processing to set a class in the HTML.

The code can be easily generated from PHP or nodejs or Angular/Typescript. In this example there are 3 images contained in an A-element (< a href='./?lang=..."> ).

The trick is that you should fetch the URL GET parameter lang and set the class selected so it will be the only one visible.

The CSS hinges on the fact that there is only one flag visible based on the class selected being present. When the mouse hovers over the container (<div class="languageselect">.....</div>) the CSS will show all flags by overriding the classes div.flag:not(.selected) and div.flag.selected and setting display:block . Then the <a href="..."> will be available to the users.

Of course there is lots of other styling possible to increase useability. This is just a starting point.

Please note the first part of the CSS-line will put the language selector on top on a fixed position. This also helps prevent the flag-container to span a whole line, messing up the :hover detection.

Happy coding!

WOrking example here: codepen

HTML:

    <div class="languageselect">
       <div class="select">
         <div class="flag ">
            <a href="./?lang=en">
              <img src="https://www.sciencekids.co.nz/images/pictures/flags120/United_Kingdom.jpg">
            </a>
         </div>
         <div class="flag selected">
            <a href="./?lang=en_us">
              <img src="https://www.sciencekids.co.nz/images/pictures/flags120/United_States.jpg">
            </a>
         </div>
         <div class="flag ">
           <a href="./?lang=nl">
             <img src="https://www.sciencekids.co.nz/images/pictures/flags96/Netherlands.jpg">
           </a>
         </div>
       </div>
    </div>

CSS:


    .languageselect {
        position: absolute;
        top: 0;
        left:0;
        z-index: 1000;
     }

     .languageselect img {
        max-height: 20px;
     }

     .languageselect div.flag:not(.selected) {
         display: none;
     }

     .languageselect div.flag.selected {
         display: block;
     }

     .languageselect:hover div.flag {
        display:block;
     }

Pianoman
  • 327
  • 2
  • 10
1

Depending on what you're trying to achieve with <select>, you may find this tip useful (if you're not within a <form>)...

just replace it with the new HTML5 <details>:

HTML:

<details>
    <summary><img src='choose_one_option.jpg'/></summary>
<ul>
  <a href=""><li><img src='foo.png'/></li></a>
  <a href=""><li><img src='bar.png'/></li></a>
</ul>
</details>

CSS:

<style>
  details summary, ul {
    list-style: none;
  }
  details summary::-webkit-details-marker {
    display: none; /* special fix, required just for Safari */
  }
  details ul {
    position: absolute;
    background: lightgrey;
    box-shadow: 10px 5px 5px rgba(0,0,0,0.5);
    margin-top: -10px;
    padding: 10px;
  }
  details li {
    padding: 10px;
    margin: 5px;
  }
  details li:hover {
    background: rgba(255,255,0,0.5);
  }
</style>

As you can see, this has some serious advantages:

  • no JS required, no frameworks, no libraries
  • very small HTML code (if you put aside all the CSS that I added to make the demo look better)
Pigeo
  • 55
  • 5
0

I tried several jquery based custom select with images, but none worked in responsive layouts. Finally i came accross Bootstrap-Select. After some modifications i was able to produce this code.

Code and github repo here

enter image description here

aslam parvaiz
  • 87
  • 1
  • 7
  • 17
    Just linking to a library is not a good answer. Linking to it, explaining why it solves the problem, and providing code using the library to do so makes for a better answer. See: [**How can I link to an external resource in a community-friendly way?**](https://meta.stackexchange.com/questions/94022/how-can-i-link-to-an-external-resource-in-a-community-friendly-way) – Kevin Brown-Silva Jan 01 '17 at 17:18
  • Guys who are interested in this bootstrap/jquery solution might look at the answer of Adarsh here: https://stackoverflow.com/questions/33726202/how-to-use-bootstrap-dropdown-as-an-html-form-select – Mi Be Feb 14 '21 at 16:00
0
<select style="font-family: bootstrap-icons !important;">
  <option value="" style="font-family: bootstrap-icons !important;">
    &#xF3CA;
  </option>
  <option value="">

  </option>
  <option value="">

  </option>
</select>
-20

UPDATE: As of 2018, this seems to work now. Tested in Chrome, Firefox, IE and Edge

UPDATE: Yes I changed the background-color, not the image, stop voting me down, showing that you can change style here is still a useful contribution.

<!DOCTYPE html>
<html>
<body>

<style>
select#newlocale option[value="volvo"]   { background-color: powderblue;   }
select#newlocale option[value="opel"]   { background-color: red;   }
select#newlocale option[value="audi"]   { background-color: green;   }
</style> 

<select id="newlocale">
  <option value="volvo"><div >Volvo</div></option>
  <option value="saab">Saab</option>
  <option value="opel">Opel</option>
  <option value="audi">Audi</option>
</select>
  
</body>
</html>
Jon
  • 1,013
  • 1
  • 10
  • 17
  • 4
    Where is the image? – BBaysinger Aug 29 '18 at 17:55
  • 2
    I was changing background colour instead of image in my example, but the style selection still proves the point. – Jon Sep 05 '18 at 11:07
  • 13
    This answer does not address the actual question (_"How to add **images** in select list?"_) at all. – skomisa Feb 13 '19 at 17:34
  • 1
    fair enough. I didn't test it with images, I wanted to apply style, which is how I ended up at this question. I presumed that { background-image:url(euro.png);} could be substituted for { background-color: green; } in my example. Im not inclined to go back and test it. – Jon Mar 21 '19 at 10:36
  • 1
    does not address original question at all. – staggart Jun 30 '19 at 05:44
  • see the comments directly above yours staggart. – Jon Jul 01 '19 at 10:21
  • Your answer states `this seems to work` which is completely wrong in every aspect. Just check https://jsfiddle.net/rpva4kzq/ -- Chrome 86.0.4240.75 fails images and FF 81.0 even fails background-color. ==> downvoted – Tino Oct 18 '20 at 13:08
  • Well FF 81 is September 2020, and my comment clearly says 2018. Also 'seems to work' means 'i did this and it worked on my machine' I never made a statement that this would always work for all time. Can I suggest you use a similar format to me: 'Update 2020 this doesnt seem to work' – Jon Oct 19 '20 at 08:03
  • -1 the OP asked how to add an *image*, whether you can change the background color or not is irrelevant to the question, making this answer useless. – pigeonburger Jul 26 '21 at 00:21