131

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.

Braiam
  • 1
  • 11
  • 47
  • 78
n0n0bstan
  • 1,790
  • 4
  • 15
  • 26
  • 4
    Possible duplicate of [Is it possible to style the drop-down suggestions when using html5 datalist?](http://stackoverflow.com/questions/10062414/is-it-possible-to-style-the-drop-down-suggestions-when-using-html5-datalist) – totymedli Nov 10 '15 at 08:02

7 Answers7

117

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.

Adrift
  • 58,167
  • 12
  • 92
  • 90
  • 4
    Relevant: list of Firefox vendor-specific CSS extensions (which includes e.g. placeholder, but nothing like datalist): https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Mozilla_Extensions – ANeves Mar 07 '14 at 12:02
  • 8
    I wish there was a way to consistantly alter native element's styles such as datalists and selects – t3__rry Oct 27 '20 at 10:13
5

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>
Orhan
  • 420
  • 1
  • 6
  • 12
  • 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. – Brian Davis Mar 24 '23 at 17:53
  • 2
    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. – kano Apr 07 '23 at 19:13
  • @kano feel free to add an answer with your suggestions. – Orhan Apr 09 '23 at 08:53
  • 3
    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. – kano Apr 10 '23 at 11:18
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>
AmitNayek
  • 158
  • 1
  • 9
1

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>
Phaelax z
  • 1,814
  • 1
  • 7
  • 19
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>
            </>
        );
    };
MrBens
  • 1,227
  • 1
  • 9
  • 19
-4

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>
Dery Reis
  • 61
  • 2
-13

try:

input[list]
{
  background: red;
}
Stephan Muller
  • 27,018
  • 16
  • 85
  • 126
  • 6
    In Firefox 30, `input[list]` styles the textbox, but not the list. In IE 11, it styles the textbox **and** the list. – Darren Griffith Jul 17 '14 at 17:27
  • This will not working for change the background color of the datalist but can use for change the background color of the input – Samz May 06 '21 at 09:47