This is how you can replace boring select tags with a new view of interaction.
<!DOCTYPE html>
<html>
<head>
<title>Select menu interaction</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<style>
html, body {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
background-color: #343334;
}
</style>
</head>
<body>
<select class="select" name="difficulty">
<option>Easy</option>
<option selected>Medium</option>
<option>Hard</option>
</select>
<script type="text/javascript" src="js/script.js"></script>
</body>
</html>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.new-interaction {
position: relative;
font-weight: 500;
}
.new-interaction select {
padding: 12px 20px 12px 10px;
opacity: 0;
user-select: none;
visibility: hidden;
pointer-events: none;
}
.new-interaction button {
outline: 0;
border: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
border-radius: 5px;
background-color: #444345;
box-shadow: 0 0 15px #2D2C2D;
font-size: 0.8rem;
color: #FFFFFF;
cursor: pointer;
}
.new-interaction button span {
position: absolute;
display: block;
right: 15px;
top: 50%;
width: 7px;
height: 7px;
margin-top: -4px;
z-index: 2;
}
.new-interaction button span:before {
content: '';
display: block;
width: 7px;
height: 7px;
transform: rotate(-45deg) scale(.75);
border-right: 2px solid #7C7B7C;
border-bottom: 2px solid #7C7B7C;
}
.new-interaction button .button-inner {
display: flex;
}
.new-interaction button .button-inner:before {
position: absolute;
content: '';
right: 0;
top: 0;
width: 30px;
height: 100%;
background: linear-gradient(to left, #444345, transparent);
z-index: 1;
}
.new-interaction button .button-element {
display: flex;
align-items: center;
text-align: left;
right: 100%;
top: 0;
width: 100%;
height: 100%;
padding: 0 10px;
}
.new-interaction button .button-element.next {
position: absolute;
width: 100%;
}
.new-interaction.animate button {
animation: bounce .45s linear;
}
.new-interaction.animate button .button-element {
animation: button .65s ease-out forwards .05s;
}
.new-interaction.animate button span {
animation: arrow .45s linear;
}
@keyframes bounce {
20% {
transform: translateX(0);
}
50% {
transform: translateX(5px);
}
}
@keyframes button {
40% {
transform: translateX(105%);
}
70% {
transform: translateX(99%);
}
100% {
transform: translateX(100%);
}
}
@keyframes arrow {
20% {
transform: translateX(20px);
opacity: 1;
}
21% {
transform: translateX(20px);
opacity: 0;
}
22% {
transform: translateX(calc(20px * -1));
opacity: 0;
}
23% {
transform: translateX(calc(20px * -1));
opacity: 1;
}
50% {
transform: translateX(4px);
}
100% {
transform: translateX(0);
}
}
(function () {
let menus = document.querySelectorAll('.select');
menus.forEach((select) => {
let wrapper = document.createElement('div');
wrapper.classList.add('new-interaction');
let selected = select.querySelector('option:checked') || select.querySelector('option');
let button = document.createElement('button');
let buttonInner = document.createElement('div');
buttonInner.classList.add('button-inner');
let buttonElement = document.createElement('div');
buttonElement.classList.add('button-element');
buttonElement.innerText = selected.innerText;
let buttonArrow = document.createElement('span');
buttonInner.appendChild(buttonArrow);
buttonInner.appendChild(buttonElement);
button.appendChild(buttonInner);
wrapper.appendChild(button);
select.parentNode.insertBefore(wrapper, select);
wrapper.appendChild(select);
wrapper.addEventListener('click', () => {
let select = wrapper.querySelector('select'),
options = select.querySelectorAll('option'),
active = select.querySelector('option:checked') || select.querySelector('option'),
button = wrapper.querySelector('button'),
buttonInner = button.querySelector('.button-inner'),
buttonElement = button.querySelector('.button-element');
if (wrapper.classList.contains('animate')) {
} else {
let selectNodes = Array.prototype.slice.call( select.children ),
nextIndex = selectNodes.indexOf(active) == selectNodes.length - 1 ? 0 : selectNodes.indexOf(active) + 1,
nextElement = document.createElement('div');
nextElement.innerText = options[nextIndex].innerText;
nextElement.classList.add('next', 'button-element');
buttonInner.appendChild(nextElement);
select.selectedIndex = nextIndex;
wrapper.classList.add('animate');
setTimeout(() => {
nextElement.classList.remove('next');
wrapper.classList.remove('animate');
buttonElement.remove();
}, 650);
}
});
});
})();