DEV Community

Cover image for πŸ”₯πŸ”₯ how to style select input in css
Modern Web
Modern Web

Posted on

44 10

πŸ”₯πŸ”₯ how to style select input in css

Hello, glad you are here. I am kunaal and today we will see how to make a custom select input, a custom options input. You can see demo below.

Demo

Video Tutorial -

If you find this article hard or for better explanation. You can watch video tutorial.

If you like the video tutorial. Please consider subscribing my youtube channel.

Let's code

In index.html inside body tag write this

<div class="container">
    <button class="select" name="select" value="options">options</button>
    <div class="options">
        <p class="item active">option 1</p>
        <p class="item">option 2</p>
        <p class="item">option 3</p>
        <p class="item">option 4</p>
    </div>
</div>
Enter fullscreen mode Exit fullscreen mode

And add some CSS

*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

*:focus{
    outline: none;
}

body{
    width: 100%;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background: #ff6767;
    font-family: 'roboto', sans-serif;
}

.container{
    position: relative;
}

.select{
    position: relative;
    width: 200px;
    height: 40px;
    border-radius: 10px;
    border: none;
    text-transform: capitalize;
    color: #fff;
    background: #292929;
    text-align: left;
    padding: 0 15px;
    font-size: 16px;
    cursor: pointer;
}

.select::after{
    content: '';
    position: absolute;
    right: 20px;
    top: 50%;
    transform: translateY(-50%) rotate(45deg);
    width: 6px;
    height: 6px;
    border-right: 2px solid #fff;
    border-bottom: 2px solid #fff;
}

.select:hover{
    background: #222222;
}

.select.active{
    background: #222222;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

.options{
    position: absolute;
    top: 40px;
    left: 0;
    width: 100%;
    height: fit-content;
    background: rgba(0, 0, 0, 0.5);
    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px;
    overflow: hidden;
    display: none;
}

.options.active{
    display: block;
}

.options .item{
    color: #fff;
    text-transform: capitalize;
    width: 100%;
    height: 30px;
    padding: 0 15px;
    line-height: 30px;
    cursor: pointer;
}

.options .item.active{
    background: #292929;
}
Enter fullscreen mode Exit fullscreen mode

we also need to write JS. So let's write some

const select = document.querySelector('.select');
const optionBox = document.querySelector('.options');
const options = [...document.querySelectorAll('.options .item')];

let activeOption = 0; // default should be 0

window.onclick = (e) => {
    if(!e.target.className.includes('select')){
        select.classList.remove('active');
        optionBox.classList.remove('active');
    } else{
        select.classList.toggle('active');
        optionBox.classList.toggle('active');
    }
}

options.forEach((item, i) => {
    item.onmousemove = () => {
        hoverOptions(i);
    }
})

const hoverOptions = (i) => {
    options[activeOption].classList.remove('active');
    options[i].classList.add('active');
    activeOption = i;
    setValue();
}

window.onkeydown = (e) => {
    if(select.className.includes('active')){
        e.preventDefault();
        if(e.key === 'ArrowDown' && activeOption < options.length - 1){
            hoverOptions(activeOption + 1);
        } else if(e.key === 'ArrowUp' && activeOption > 0){
            hoverOptions(activeOption - 1);
        } else if(e.key === 'Enter'){
            select.classList.remove('active');
            optionBox.classList.remove('active');
        }
    }
}

const setValue = () => {
    select.innerHTML = select.value = options[activeOption].innerHTML;
}

setValue();
Enter fullscreen mode Exit fullscreen mode

I hope you understood everything. If you have any doubt or you find any mistake that I made or you have any suggestion feel free to ask me in comment.

If you are interested in programming and want to know how I a 15yr old teen do coding make these design. You can follow me on my Instagram. I am also planning to post my game development stuff on Instagram.

My youtube Channel, Instagram

Tiugo image

Modular, Fast, and Built for Developers

CKEditor 5 gives you full control over your editing experience. A modular architecture means you get high performance, fewer re-renders and a setup that scales with your needs.

Start now

Top comments (7)

Collapse
 
jameslivesey profile image
James Livesey β€’

Looks really nice, but unfortunately this isn't accessible at all to blind/visually impaired users who use screen readers, or users with reduced motor ability who use either the keyboard only or switches. Would love to see an accessible version! Until then, I'm gonna stick to the default semantic <select>...

Collapse
 
themodernweb profile image
Modern Web β€’ β€’ Edited

Ah ! My bad I totally forgot this scenario but no worry you can use this select in your forms you just have to do some changes.

Step 1-. Inside CSS file remove this line

*:focus{
    outline: none;
}
Enter fullscreen mode Exit fullscreen mode

Step 2- Then in JS add focus and blur event to select button

select.onfocus = () => {
    select.classList.add('focus');
}

select.onblur = () => {
    select.classList.remove('focus');
}
Enter fullscreen mode Exit fullscreen mode

Step 3- And last modify window.keypress function little bit.

window.onkeydown = (e) => {
    if(select.className.includes('active') || select.className.includes('focus')){
        if(e.key === 'ArrowDown' && activeOption < options.length - 1){
            e.preventDefault();
            hoverOptions(activeOption + 1);
        } else if(e.key === 'ArrowUp' && activeOption > 0){
            e.preventDefault();
            hoverOptions(activeOption - 1);
        } else if(e.key === 'Enter'){
            e.preventDefault();
            select.classList.remove('active');
            optionsBox.classList.remove('active');
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

And now you can easily access this select button from tab and change options with keys.

I hope you find this helpful.
Thank you.

Collapse
 
themodernweb profile image
Modern Web β€’

Ohh! My bad I totally forgot this scenario but no worry you can use this select in your forms you just have to do some changes.

  1. Inside CSS file remove this line
*:focus{
    outline: none;
}
Enter fullscreen mode Exit fullscreen mode
  1. Then in JS add focus and blur event to select button
select.onfocus = () => {
    select.classList.add('focus');
}

select.onblur = () => {
    select.classList.remove('focus');
}
Enter fullscreen mode Exit fullscreen mode
  1. And last modify window.keypress function little bit.
window.onkeydown = (e) => {
    if(select.className.includes('active') || select.className.includes('focus')){
        if(e.key === 'ArrowDown' && activeOption < options.length - 1){
            e.preventDefault();
            hoverOptions(activeOption + 1);
        } else if(e.key === 'ArrowUp' && activeOption > 0){
            e.preventDefault();
            hoverOptions(activeOption - 1);
        } else if(e.key === 'Enter'){
            e.preventDefault();
            select.classList.remove('active');
            optionsBox.classList.remove('active');
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

And now you can easily access this select button from tab and change options with keys.

I hope you find this helpful.
Thank you.

Collapse
 
sfritsch09 profile image
Sebastian Fritsch β€’

Thanks so much for that and I managed to create a React version of yours :)

export default function Selector({ label, value, onChange, options }) {
    const selectRef = useRef();
    const optionsRef = useRef();
    const [hover, setHover] = useState('');

    const handleOptions = (e) => {
        if (!e.target.className.includes('select')) {
            selectRef.current.classList.remove('active');
            optionsRef.current.classList.remove('active');
        } else {
            selectRef.current.classList.toggle('active');
            optionsRef.current.classList.toggle('active');
        }
    };
    return (
        <SelectWrapper>
            <label>{label}</label>
            <button ref={selectRef} className="select" onClick={handleOptions}>
                {value}
                <div ref={optionsRef} className="options">
                    {options.map((option, index) => (
                        <p
                            key={index}
                            onClick={onChange}
                            className={hover === option.value || value === option.value ? 'item active' : 'item'}
                            value={option.value}
                            onMouseOver={() => setHover(option.value)}
                        >
                            {option.label}
                        </p>
                    ))}
                </div>
            </button>
        </SelectWrapper>
    );
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
guscarpim profile image
Gustavo Scarpim β€’

haha very nice!

Collapse
 
mafee6 profile image
Mafee7 β€’

Chrome should add ::-webkit-options-dropdown
L

Collapse
 
hosseinmobarakian profile image
Hossein Mobarakian β€’

ty for this tutorial

Image of Quadratic

Free AI chart generator

Upload data, describe your vision, and get Python-powered, AI-generated charts instantly.

Try Quadratic free

πŸ‘‹ Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay