Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Tray2's avatar
Level 73

Styling of Datalists <input list="artists">?

I've been tinkering with NativePhp the last couple of days, and run into a little bit of an annoying issue with styling.

I have the following element and Tailwind styles.

<input list="artists"
            name="artist_name"
             id="artist_name"
             class="col-span-6 bg-gray-700 focus:border-b-2 focus:border-amber-500 outline-none rounded-xl p-2"
             value="{{ old('artist_name') }}">
 <datalist id="artists">
		@foreach($artists as $artist)
 				<option value="{{ $artist->name }}"></option>
   		@endforeach
   </datalist>

Now this looks great when I type a new value into the datalist, but as soon as the value already exists in the datalist, and I select it, the styles get overridden, I get white background and black text on the datalist input.

I don't think there is a CSS way around it, but I thought I would put the question out here to see if someone has solved this.

I want my styles bg-gray-700 text-amber-100 to be applied to the selected option.

0 likes
1 reply
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

Styling the <datalist> and its options is quite limited because the appearance of the dropdown is controlled by the browser and not easily customizable with CSS. However, there are a few workarounds you can consider to achieve a more consistent look.

Workaround 1: Custom Dropdown with JavaScript

One approach is to create a custom dropdown using JavaScript and CSS, which gives you full control over the styling. Here’s an example of how you can achieve this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Custom Datalist</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
    <style>
        .custom-dropdown {
            position: relative;
        }
        .custom-dropdown-list {
            position: absolute;
            top: 100%;
            left: 0;
            right: 0;
            background-color: #2d3748; /* bg-gray-700 */
            border: 1px solid #cbd5e0; /* border-gray-300 */
            border-radius: 0.5rem; /* rounded-xl */
            max-height: 200px;
            overflow-y: auto;
            z-index: 1000;
        }
        .custom-dropdown-list option {
            padding: 0.5rem;
            cursor: pointer;
        }
        .custom-dropdown-list option:hover {
            background-color: #4a5568; /* bg-gray-600 */
        }
    </style>
</head>
<body class="p-6 bg-gray-800 text-white">

<div class="custom-dropdown">
    <input type="text" id="artist_name" name="artist_name" class="col-span-6 bg-gray-700 focus:border-b-2 focus:border-amber-500 outline-none rounded-xl p-2" autocomplete="off">
    <div id="dropdown-list" class="custom-dropdown-list hidden">
        @foreach($artists as $artist)
            <option value="{{ $artist->name }}">{{ $artist->name }}</option>
        @endforeach
    </div>
</div>

<script>
    document.addEventListener('DOMContentLoaded', function () {
        const input = document.getElementById('artist_name');
        const dropdown = document.getElementById('dropdown-list');

        input.addEventListener('input', function () {
            const value = this.value.toLowerCase();
            const options = dropdown.querySelectorAll('option');
            let hasMatch = false;

            options.forEach(option => {
                if (option.value.toLowerCase().includes(value)) {
                    option.style.display = 'block';
                    hasMatch = true;
                } else {
                    option.style.display = 'none';
                }
            });

            dropdown.classList.toggle('hidden', !hasMatch);
        });

        dropdown.addEventListener('click', function (e) {
            if (e.target.tagName === 'OPTION') {
                input.value = e.target.value;
                dropdown.classList.add('hidden');
            }
        });

        document.addEventListener('click', function (e) {
            if (!dropdown.contains(e.target) && e.target !== input) {
                dropdown.classList.add('hidden');
            }
        });
    });
</script>

</body>
</html>

Explanation:

  1. HTML Structure: The input field and a custom dropdown list are wrapped in a container.
  2. CSS Styling: Tailwind CSS is used for styling, and additional custom styles are added for the dropdown list.
  3. JavaScript Functionality:
    • The input event listener filters the dropdown options based on the input value.
    • The click event listener on the dropdown options sets the input value and hides the dropdown.
    • A document click event listener hides the dropdown when clicking outside of it.

Workaround 2: Using a Third-Party Library

Another approach is to use a third-party library like Select2 or jQuery UI Autocomplete, which provides more styling options and better control over the dropdown appearance.

Conclusion

While native <datalist> elements have limited styling capabilities, creating a custom dropdown with JavaScript or using a third-party library can help you achieve the desired look and feel.

Please or to participate in this conversation.