Is there a way to apply a CSS style on HTML5 datalist options?
Asked Answered
K

7

139

I would like to modify the way that the list of the different options of my datalist are displayed. Is it possible to apply on it some CSS properties ?

<input list="languages" id="language_id">
<datalist id="languages">
      <option value="html">HTML</option>
      <option value="java">Java</option>
      <option value="perl">Perl</option>
      <option value="php">PHP</option>
      <option value="ruby-on-rails">Ruby on Rails</option>
</datalist>

I tried

option {
    background: red;
}

but it does not seem to work.

Kileykilgore answered 3/12, 2012 at 23:12 Comment(1)
Possible duplicate of Is it possible to style the drop-down suggestions when using html5 datalist?Intricacy
D
118

Like select elements, the datalist element has very little flexibility in styling. You cannot style any of the suggested terms if that's what your question was asking.

Browsers define their own styles for these elements.

Divider answered 3/12, 2012 at 23:48 Comment(5)
Relevant: list of Firefox vendor-specific CSS extensions (which includes e.g. placeholder, but nothing like datalist): developer.mozilla.org/en-US/docs/Web/CSS/Reference/…Battled
I wish there was a way to consistantly alter native element's styles such as datalists and selectsTortuga
Eh, this might have been true in 2013, but now you can just do something like datalist option { font-size: 0.8em; padding: 0.3em 1em; background-color: #ccc; cursor: pointer; } Works just fine.Hooke
@RWC: you must live in a different universe than the rest of us. In our universe, even a simple datalist option {color:red;} is completely ignored.Farmstead
Especially for martian Martha a codepen: codepen.io/r-w-c/pen/KKbYbxW Uncomment datalist option and see how the impossible happens. Sigh!Hooke
C
11

I found this codepen where someone did it: https://codepen.io/sidd_dev/pen/qBRWNQQ?editors=1010

enter image description here

I tested it with

  • Chrome 108.0.5359.99 (Official Build) (64-bit)
  • Firefox 107.0.1 (64-bit

You should check https://caniuse.com/?search=datalist for more details regarding browser support.

input.onfocus = function () {
  browsers.style.display = 'block';
  input.style.borderRadius = "5px 5px 0 0";  
};
for (let option of browsers.options) {
  option.onclick = function () {
    input.value = option.value;
    browsers.style.display = 'none';
    input.style.borderRadius = "5px";
  }
};

input.oninput = function() {
  currentFocus = -1;
  var text = input.value.toUpperCase();
  for (let option of browsers.options) {
    if(option.value.toUpperCase().indexOf(text) > -1){
      option.style.display = "block";
  }else{
    option.style.display = "none";
    }
  };
}
var currentFocus = -1;
input.onkeydown = function(e) {
  if(e.keyCode == 40){
    currentFocus++
   addActive(browsers.options);
  }
  else if(e.keyCode == 38){
    currentFocus--
   addActive(browsers.options);
  }
  else if(e.keyCode == 13){
    e.preventDefault();
        if (currentFocus > -1) {
          /*and simulate a click on the "active" item:*/
          if (browsers.options) browsers.options[currentFocus].click();
        }
  }
}

function addActive(x) {
    if (!x) return false;
    removeActive(x);
    if (currentFocus >= x.length) currentFocus = 0;
    if (currentFocus < 0) currentFocus = (x.length - 1);
    x[currentFocus].classList.add("active");
  }
  function removeActive(x) {
    for (var i = 0; i < x.length; i++) {
      x[i].classList.remove("active");
    }
  }
fieldset {
  border: 1px solid blue;
  width: 360px;
  border-radius: 5px;
}

legend, label{
  color: blue; 
  font-size: 24px;
  font-family: sans-serif;
}

input {
  font-size: 18px;
  padding: 5px;
  height: 35px;
  width: 350px;
  border: 1px solid blue;
  outline: none;
  border-radius: 5px;
  color: blue;
/*   border-bottom: none; */
}
datalist {
  position: absolute;
  background-color: white;
  border: 1px solid blue;
  border-radius: 0 0 5px 5px;
  border-top: none;
  font-family: sans-serif;
  width: 350px;
  padding: 5px;
  max-height: 10rem;
  overflow-y: auto
  
}

option {
  background-color: white;
  padding: 4px;
  color: blue;
  margin-bottom: 1px;
   font-size: 18px;
  cursor: pointer;
}

option:hover,  .active{
  background-color: lightblue;
}
  <fieldset>
    <legend>
      Datalist Form
    </legend>
    <label>Select Browser</label>
    <input  autocomplete="off" role="combobox" list="" id="input" name="browsers" placeholder="Select your fav browser">
  <!-- Its important that you keep list attribute empty to hide the default dropdown icon and the browser's default datalist -->

  <datalist id="browsers" role="listbox">
    <option value="Internet Explorer">Internet Explorer</option>
  <option value="Chrome">Chrome</option>
  <option value="Safari">Safari</option>
    <option value="Microsoft Edge">Microsoft Edge</option>
    <option value="Firefox">Firefox</option><option value="Microsoft Edge">Microsoft Edge</option>
    <option value="Firefox">Firefox</option><option value="Microsoft Edge">Microsoft Edge</option>
    <option value="Firefox">Firefox</option><option value="Microsoft Edge">Microsoft Edge</option>
    <option value="Firefox">Firefox</option><option value="Microsoft Edge">Microsoft Edge</option>
    <option value="Firefox">Firefox</option><option value="Microsoft Edge">Microsoft Edge</option>
    <option value="Firefox">Firefox</option><option value="Microsoft Edge">Microsoft Edge</option>
    <option value="Firefox">Firefox</option><option value="Microsoft Edge">Microsoft Edge</option>
    <option value="Firefox">Firefox</option><option value="Microsoft Edge">Microsoft Edge</option>
    <option value="Firefox">Firefox</option><option value="Microsoft Edge">Microsoft Edge</option>
    <option value="Firefox">Firefox</option>
  </datalist>
<!--     <br>
    <br>
    <label for="pwd"> Password </label>
    <input id="pwd" type="password">
     -->
  </fieldset>
Cariecaries answered 13/12, 2022 at 14:54 Comment(5)
Interesting how there's 100 votes for the answer saying it's impossible and only like 2 votes for the answer that says "here is a literal example of how it's possible." I get that there are nuances, but still.Belligerence
The "here is a literal example of how it's possible" mostly just recreates the select/dropdown behaviour with JavaScript - the datalist and option elements could just as easily be spans or divs at this point... You can see the example lacking native functionality like click-outside handling, etc.Thus
@Thus feel free to add an answer with your suggestions.Cariecaries
I'm just trying to highlight why the other 100-vote-answers claim it's not possible with a simple or native solution. I don't think me not providing my own solution in any way invalidates the truth behind my statement. That's like asking a boxing commentator or coach to show their boxing career stats before you listen their critique or advice. People who choose this solution should be made aware of its shortcomings, that's all.Thus
It's like saying... Yes, you can do that. You just have to throw everything to the trash and recreate the whole thing from scratch. C'mon man, Javascript is turing-complete, what can't you do with it? In fact, someone once demonstrated that CSS is also turing-complete. This is not what people usually mean when they say whether you can do something or not in JS.Strobila
C
5

The codepen posted by @Orhan left room for a bit of improvement I thought and figured I'd share a solution based on that code. This properly hides the dropdown when it loses focus or when no options are available. Was going to tidy it up more and make it a jquery plugin but figured I'd post the vanilla code first. This also has a responsive width to match the length of the input field but maintain a minimum that will extend beyond the input's width if need be to show the full option text.

function fancyDropdown(inputId){
    id = document.getElementById(inputId);
    datalist = id.nextElementSibling;
  var minWidth = datalist.offsetWidth;
    

  function outputsize(){
    if (id.offsetWidth < minWidth ){
      datalist.style.minwidth = id.offsetWidth+'px';
    }else{
      datalist.style.width = id.offsetWidth+'px';
    }
  }

  new ResizeObserver(outputsize).observe(id);


  id.addEventListener("input", function(e){
    datalist.style.display = "block";
    var text = id.value.toUpperCase();
    let hide = 1;
    for (let option of datalist.options) {
      if(option.value.toUpperCase().indexOf(text) > -1){
        option.style.display = "block";
        hide = 0;
      }else{
        option.style.display = "none";
      }
    }
    if (hide){
        datalist.style.display = "none";
    }
  });



  id.addEventListener("click", function(e){
  
    let hide = 1;
    for (let option of datalist.options) {
        if (window.getComputedStyle(option, null).display == "block") hide = 0;
    }
  
    if (datalist.style.display == "block" || hide == 1){
      datalist.style.display = "none";
    }else{
      datalist.style.display = "block";
    }
  });
  

  document.addEventListener("click", function(e){

    if (e.target.tagName == "OPTION"){
      id.value = e.target.value;
    }
    if (e.target.tagName !== "DATALIST" && e.target.tagName !== "INPUT"){
      datalist.style.display = "none";
    }

  });

    datalist.style.display = "none";

}


fancyDropdown('product');
body{background: #272b2f;color:white}
input{transition: 0.2s;width:50%;margin:0;box-sizing:border-box;padding:8px;border:1px solid #404449;outline:none;border-radius:4px;background:#212529;color:#e7e7e7}

input:focus{border: 1px solid #db9c2e; box-shadow: 0px 0px 3px 0px #db9c2e;border-radius:4px 4px 0 0;}

datalist {
  margin-top:-1px;
  overflow-y: auto;
  box-sizing: border-box;
  display: block;
  position: absolute;
  background-color: #212529;
  border: 1px solid #404449;
  border-radius: 0 0 4px 4px;
  font-family: sans-serif;
  padding: 5px;
  max-height: 10rem;
  border: 1px solid #db9c2e; box-shadow: 0px 0px 3px 0px #db9c2e;
}

option {
  padding: 4px;
  color: #e7e7e7;
  margin-bottom: 1px;
  font-size: 18px;
  cursor: pointer;
  display:block;
}

option:hover{background-color: #3f4348;}
<input type="text" id="product" name="product" list="" />
<datalist id="mylist">
  <option value="John Paul Jacobs">John Paul Jacobs</option>
  <option value="Dorothy Tornado">Dorothy Tornado</option>
  <option value="Inigo Montoya">Inigo Montoya asdf asdf asdfadfasdfs</option>
  <option value="John Paul Jacobs">John Paul Jacobs</option>
  <option value="Dorothy Tornado">Dorothy Tornado</option>
  <option value="Inigo Montoya">Inigo Montoya asdf asdf asdfadfasdfs</option>
  <option value="John Paul Jacobs">John Paul Jacobs</option>
  <option value="Dorothy Tornado">Dorothy Tornado</option>
  <option value="Inigo Montoya">Inigo Montoya asdf asdf asdfadfasdfs</option>
  <option value="John Paul Jacobs">John Paul Jacobs</option>
  <option value="Dorothy Tornado">Dorothy Tornado</option>
  <option value="Inigo Montoya">Inigo Montoya asdf asdf asdfadfasdfs</option>
  <option value="John Paul Jacobs">John Paul Jacobs</option>
  <option value="Dorothy Tornado">Dorothy Tornado</option>
  <option value="Inigo Montoya">Inigo Montoya asdf asdf asdfadfasdfs</option>
</datalist>

<div>
<p>
putting some stuff here for the big brown fox running over the river to get the turtle to feed to its pet frog.
</p>
</div>
Creativity answered 5/5, 2023 at 3:22 Comment(0)
S
2

can we try with datalist-css this package Link :- enter link description here

here is stackblitz example

https://angular-datalist-option-hvvgcz.stackblitz.io

css would be :--

datalist {
  position: absolute;
  max-height: 20em;
  border: 0 none;
  overflow-x: hidden;
  overflow-y: auto;
}

datalist option {
  font-size: 0.8em;
  padding: 0.3em 1em;
  background-color: #ccc;
  cursor: pointer;
}

/* option active styles */
datalist option:hover,
datalist option:focus {
  color: #fff;
  background-color: #036;
  outline: 0 none;
}

#browserdata option {
  font-size: 1.8em;
  padding: 0.3em 1em;
  background-color: #ccc;
  cursor: pointer;
}

Html would be : --

<label for="browser">browser:</label>

<input
  list="browserdata"
  id="browser"
  name="browser"
  size="50"
  autocomplete="off"
/>

<datalist id="browserdata">
  <option>Brave</option>
  <option>Chrome</option>
  <option>Edge</option>
  <option>Firefox</option>
  <option>Internet Explorer</option>
  <option>Opera</option>
  <option>Safari</option>
  <option>Vivaldi</option>
  <option>other</option>
</datalist>
Successful answered 22/6, 2022 at 17:46 Comment(0)
A
0

EDIT:
After looking at few other libraries, I found out react-datalist-input provides the easiest way to interact with datalists in react, style and functionality alike.

You can access styles via

.datalist-input  

A simple code snippet below:

const DataListWrapper = styled.div`
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 6px;

    .datalist-input {
        width: 50%;
        color: black;
    }
`;

const SomeComponent = () => {
    return (
        <DataListWrapper>
            <ReactDataList
                forcePoly
                placeholder="Search Something..."
                list="my_list"
                options={options}
                onOptionSelected={(e) => foo(e)}
            />
        </DataListWrapper>
    );
};

Old answer:
(note: react-datalist is not being maintained and some of its dependencies are deprecated)

When working with react, you can style the options and the datalist itself using

react-datalist

https://www.npmjs.com/package/react-datalist

You can access these using CSS or styled-components

.react-datalist  
.react-datalist-option

Here is a simple code snippet using styled-components:

    const DataListWrapper = styled.div`
          display: flex;
          justify-content: center;
          align-items: center;
          margin-top: 6px;
    
          .datalist-input {
              width: 50%;
              color: black;
          }
    `;
    
    const SomeComponent = () => {
        return (
            <>
                <DataListWrapper>
                    <DataListInput
                        placeholder="Search Something..."
                        items={items}
                        onSelect={DoSomething}
                    />
                </DataListWrapper>
            </>
        );
    };
Annamariaannamarie answered 10/5, 2021 at 7:32 Comment(0)
K
-6

You can create an alternative Datalist with Jquery

$(document).on('dblclick', 'input[list]', function(event){
    event.preventDefault();
        var str = $(this).val();
    $('div[list='+$(this).attr('list')+'] span').each(function(k, obj){
            if($(this).html().toLowerCase().indexOf(str.toLowerCase()) < 0){
                $(this).hide();
            }
        })
    $('div[list='+$(this).attr('list')+']').toggle(100);
    $(this).focus();
})

$(document).on('blur', 'input[list]', function(event){
        event.preventDefault();
        var list = $(this).attr('list');
        setTimeout(function(){
            $('div[list='+list+']').hide(100);
        }, 100);
    })

    $(document).on('click', 'div[list] span', function(event){
        event.preventDefault();
        var list = $(this).parent().attr('list');
        var item = $(this).html();
        $('input[list='+list+']').val(item);
        $('div[list='+list+']').hide(100);
    })

$(document).on('keyup', 'input[list]', function(event){
        event.preventDefault();
        var list = $(this).attr('list');
    var divList =  $('div[list='+$(this).attr('list')+']');
    if(event.which == 27){ // esc
        $(divList).hide(200);
        $(this).focus();
    }
    else if(event.which == 13){ // enter
        if($('div[list='+list+'] span:visible').length == 1){
            var str = $('div[list='+list+'] span:visible').html();
            $('input[list='+list+']').val(str);
            $('div[list='+list+']').hide(100);
        }
    }
    else if(event.which == 9){ // tab
        $('div[list]').hide();
    }
    else {
        $('div[list='+list+']').show(100);
        var str  = $(this).val();
        $('div[list='+$(this).attr('list')+'] span').each(function(){
          if($(this).html().toLowerCase().indexOf(str.toLowerCase()) < 0){
            $(this).hide(200);
          }
          else {
            $(this).show(200);
          }
        })
      }
    })
* {
  scrollbar-width: thin;
    scrollbar-color: #BBB #EEE;
}

*::-webkit-scrollbar {
  width: 10px;
}

*::-webkit-scrollbar-track {
  background: #C0C3C6;
}

*::-webkit-scrollbar-thumb {
  background-color: #888;
  border-radius: 10px;
  border: 3px solid #C0C3C6;
}

table {
    width: 400px;
    margin: 0 auto;
    background: #EEE;
    font-family: Arial;
    padding: 10px 30px;
  border-radius: 5px;
  box-shadow: 0 5px 5px -5px #000;
    --border: 1px solid #ABC;
}
table td {
  padding-bottom: 10px;
}
table h4 {
  text-align: center;
  color: #567;
  border: 1px solid #567;
  border-radius: 3px;
  padding: 15px 0;
}
input {
    padding: 10px;
    font-size: 1em;
    width: calc(100% - 20px);
    border: var(--border);
    border-radius: 3px;
}
input[list]:focus {
    outline: none;
}
input[list] + div[list] {
    display: none;
    position: absolute;
    width: 100%;
    max-height: 164px;
    overflow-y: auto;
    max-width: 330px;
    background: #FFF;
    border: var(--border);
    border-top: none;
  border-radius: 0 0 5px 5px;
  box-shadow: 0 3px 3px -3px #333;
    z-index: 100;
}
input[list] + div[list] span {
    display: block;
    padding: 7px 5px 7px 20px;
    color: #069;
    text-decoration: none;
    cursor: pointer;
}
input[list] + div[list] span:not(:last-child) {
  border-bottom: 1px solid #EEE;
}
input[list] + div[list] span:hover {
    background: rgba(100, 120, 140, .2);
}

table .instructions {
  font-size: .9em;
  color: #900;
}
table .instructions b {
  color: #123;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<table width="400">
    <tr>
        <td> <h4>DATALIST STYLING ALTERNATIVE</h4> </td>
    </tr>
    <tr>
        <td>
            <div>Programming languages</div>
            <input type="text" name="language" list="list-language">
            <div list="list-language">
                <span>CSharp</span>
                <span>Delphi</span>
                <span>Flutter</span>
                <span>Java</span>
                <span>Java Script</span>
                <span>PHP</span>
                <span>Python</span>
                <span>Ruby</span>
                <span>SAP</span>
                <span>Visual Basic</span>
            </div>
        </td>
    </tr>
    <tr>
        <td>
            <div>Cities</div>
            <input type="text" name="cities" list="list-cities">
            <div list="list-cities">
                <span>Athens</span>
                <span>Beijing</span>
                <span>Berlin</span>
                <span>Cairo</span>
                <span>Lisbon</span>
        <span>London</span>
        <span>Mexico City</span>
                <span>Moscow</span>
                <span>New York</span>
                <span>Rio de Janeiro</span>
                <span>Rome</span>
                <span>Tokyo</span>
            </div>
        </td>
    </tr>
  <tr>
    <td>
      <div class='instructions'>
        <b>INSTRUCTIONS:</b><hr>
        <p><b>Double click on the input:</b><br>Show/hide the datalist.</p>
        <p><b>Press esc on the input:</b><br>Hides datalist if visible.</p>
        <p><b>Onkeypress in the input:</b><br>Displays the datalist filtering according to the entered string.</p>
        <p><b>On pressing enter:</b><br>Ff there is only 1 element in the datalist, this value will be loaded into the input.</p>
      </div>
    <td>
  </tr>
</table>
Kronfeld answered 6/3, 2021 at 19:41 Comment(3)
Why are you using table based layout?Guardrail
The original question is how to apply styles not what are the alternatives.Talkingto
it works but it's not what the question askedTrela
B
-16

try:

input[list]
{
  background: red;
}
Beau answered 9/5, 2014 at 3:42 Comment(2)
In Firefox 30, input[list] styles the textbox, but not the list. In IE 11, it styles the textbox and the list.Vizor
This will not working for change the background color of the datalist but can use for change the background color of the inputFoucquet

© 2022 - 2024 — McMap. All rights reserved.