Build a Custom Modern Volume Slider using HTML CSS and JS
Enhance your user interface with a sleek and interactive volume control widget. In this blog post, we'll explore how to design and implement a stylish volume control using HTML, CSS, and JavaScript. From the SVG iconography to the dynamic visual feedback, every step is covered to elevate your web design skills.
Also Read: Star Rating System using HTML and CSS only
HTML Structure
The foundation of our stylish volume control lies in the HTML markup. Let's break down the structure and understand the role of each element in creating an intuitive user interface.
<div class="main-container">
<div class="box">
<svg viewBox="-10 -14 52 52" xmlns="http://www.w3.org/2000/svg" width="50">
<g stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="transparent">
<path stroke-width="4" fill="white" d="M8 9H5v6h3l5 4V5L8 9z"></path>
<path d="M18.5 8a3.657 5 0 010 8" class="low hidden"></path>
<path d="M23 6a2.657 6.5 0 010 12" class="medium hidden"></path>
<path d="M27 3a3.5 9.1 0 010 18" class="high hidden"></path>
<path d="M20 9L26 15M26 9L20 15" class="mute hidden"></path>
</g>
</svg>
<div class="field">
<input type="range" id="volume" value="50">
</div>
</div>
</div>
The "main-container" serves as the overarching container for our volume control. Inside it, we have a "box" that encapsulates the entire volume control widget. The svg element contains a group (g) defining the styling for our SVG paths. Various path elements within the group form the volume icon.
The "field" wraps an input element of type range with the ID volume and an initial value of 50. This input range serves as the volume control slider.
CSS Styling
Now that we've established the HTML structure for our volume control, let's dive into the CSS styling. We'll explore how to enhance the visual appeal and responsiveness of our volume control, creating a modern and engaging user interface.
:root {
--width: 150px;
}
.main-container {
min-width: 100px;
min-height: 100vh;
}
.main-container,
.box,
.field {
display: flex;
align-items: center;
justify-content: center;
}
.box {
gap: 5px;
flex-direction: column;
}
- We begin by defining a custom property --width to set the base width for our volume control. This variable will be used throughout the styling to ensure consistency and ease of customization.
- The .box class styles the overarching container, ensuring a clean and organized layout. Flexbox properties are employed to center and align the elements properly.
Styling the Volume Control Slider
.field {
height: var(--width);
}
#volume {
height: 6px;
cursor: pointer;
appearance: none;
overflow: hidden;
width: var(--width);
border-radius: 10px;
transform: rotate(-90deg);
transition: height .15s ease-in;
background: rgb(82, 82, 82);
}
- The .field class and #volume selector style the volume control slider.
- Flex properties are used for alignment, and the --width variable ensures consistency.
- The #volume selector styles the input range, setting its appearance, dimensions, cursor, and background.
Styling Thumb Shadows for Different Browsers
#volume::-moz-range-thumb {
width: 0;
height: 0;
border: none;
box-shadow: calc(var(--width) * -1) 0 0 var(--width) #fff;
}
#volume::-webkit-slider-thumb {
-webkit-appearance: none;
width: 0;
height: 0;
border: none;
box-shadow: calc(var(--width) * -1) 0 0 var(--width) #fff;
}
- These pseudo-selectors style the slider thumb specifically for Mozilla Firefox (::-moz-range-thumb) and Webkit browsers (::-webkit-slider-thumb).
- They utilize box-shadow to create the appearance of a thumb with the same width as our defined custom property.
Other Styles
#volume:hover {
height: 10px;
}
.fa-solid {
color: white;
flex-grow: 1;
}
.hidden {
visibility: hidden;
opacity: 0 !important;
}
svg {
cursor: pointer;
}
path {
transition: .3s;
opacity: 1;
}
- The :hover pseudo-class adds a subtle height increase to the volume control slider, enhancing the user's visual feedback during interaction.
- If you decide to incorporate Font Awesome icons, this style ensures that the icon has a white color and flexible growth within its container.
- The path selector sets a smooth transition and initial opacity for the SVG paths. This prepares the stage for dynamic changes based on user interaction.
JavaScript Magic
Variable Declarations and DOM Selection:
const input = document.querySelector('input');
const svg = document.querySelector('svg')
const alls = Array.from(document.querySelectorAll('.low, .medium, .high, .mute'))
let mute = false;
let lastLevel = 50;
We begin by selecting the input element and the svg element from the HTML. Additionally, all elements with classes 'low', 'medium', 'high' and 'mute' are stored in the 'alls' array. 'mute' is a boolean variable to track the mute state and 'lastLevel' stores the last volume level.
Also Read: Legend Form using HTML CSS and JavaScript | See Magic on Hover
Function VolLevel()
function VolLevel(val) {
val === 0 ? alls[3].classList.remove('hidden') : '';
for (let i = 0; i < val; i++) {
alls[i].classList.remove('hidden')
}
}
This function controls the visibility of volume level elements based on the provided value (val). If val is 0, it removes the 'hidden' class from the mute element. It removes the 'hidden' class from the elements up to the given val.
Function updateVol()
function updateVol() {
alls.forEach(elem => elem.classList.add('hidden'));
const val = input.value;
const level = val >= 70 ? 3 : (val >= 30 ? 2 : (val > 0 ? 1 : 0));
VolLevel(level);
}
This function updates the volume level based on the input value. It hides all volume level elements by adding the 'hidden' class. It determines the volume level (level) based on the input value and calls VolLevel with this level.
Function toggleVol():
function toggleVol() {
const interval = setInterval(() => {
const value = parseInt(input.value);
if (!mute) {
input.value = Math.max(0, value - 1);
if (value === 0) {
clearInterval(interval);
mute = true;
}
} else {
if (value < lastLevel) {
input.value = Math.min(100, value + 1);
} else {
clearInterval(interval);
mute = false;
}
}
updateVol();
}, 1);
}
This function toggles the volume between mute and unmute states. It starts an interval that adjusts the volume until it reaches the desired state (mute or unmute). The interval stops when the desired state is reached, and updateVol is called to update the volume level.
Event Listeners:
input.addEventListener('input', updateVol);
input.addEventListener('change', () => {
mute = input.value === 0;
lastLevel = input.value;
});
svg.addEventListener('click', toggleVol);
An event listener is added to the input element to call updateVol when the input value changes. Another event listener is added to the input element to update mute and lastLevel variables when the input value changes. An event listener is added to the SVG element to call toggleVol when it's clicked.
Initial Update:
updateVol();
This line calls updateVol initially to set up the volume level based on the input's initial value.
This flow describes how the code works in response to user interactions:
- Clicking the SVG element: Toggles the volume adjustment (starts or stops adjusting volume).
- Changing the input range value: Updates the displayed volume levels and mute state.
- Initial load: Sets initial volume level and displayed volume levels based on the initial value of the input range.
Throughout this comprehensive guide, we've covered the HTML structure, CSS styling, and JavaScript logic required to bring your volume control to life.
As you wrap up this tutorial, consider exploring further enhancements and modifications. Experiment with additional CSS animations, explore different iconography, or integrate the volume control into a broader audio visual experience.
Remember, web development is a creative endeavor and continuous learning is key. Stay curious, keep experimenting and leverage the knowledge gained here to build even more captivating and user-friendly interfaces. Thank you for joining us on this coding journey.