Select menu interaction

About

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);

				}

			});
	});
})();