Home > Software engineering >  The changing volume icon pushes the volume slider. css problem
The changing volume icon pushes the volume slider. css problem

Time:04-21

is there an easy fix to separate the volume icon from the volume slider? I have the volume icon change depending on the slider value but it feels janky because the size of the icon changes and pushes everything. I think you can c/p the code on replit and see the problem with the volume slider. I tried aligning it to the right or changing the position using transform but it doesn't seem to fix the problem.

<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <link href="style.css" rel="stylesheet" type="text/css" />
  <link
    rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
  />
</head>

<body>
<div >
  <video id="myVideo" poster="Poke_Ball.png">
  <source src="https://www.youtube.com/watch?v=Y3xgmGSnzlU" >    
  </video>
  <div >
      <div >
        <div ></div>
      </div>

      <button id="btnPlay"><i ></i></button>
      <button id="btnPause" ><i ></i></button>
      <button id="volumeNone" ><i ></i></button>
      <button id="volumeLow" ><i ></i></button>
      <button id="volumeHigh"><i ></i></button>
      <input type="range"  min="0" max="1" step="0.01" value=".5"/>
    </div>
</div>
  <script src="script.js"></script>
</body>

</html>

.hidden {
    display: none;
}
.video-player {
  max-width: 100%;
  position: relative;
  overflow: hidden;
}
.player-controls {
  display: flex;
  position: absolute;
  bottom: 0;
  width: 100%;
  transform: translateY(100%) translateY(-5px);
  transition: 0.3s;
  flex-wrap: wrap;
  background: rgba(0, 0, 0, 0.6);
}
.video-player:hover .player-controls {
  transform: translateY(0);
}
.video-progress {
  position: relative;
  display: flex;
  width: 100%;
  height: 5px;
  transition: 0.3s;
  background: rgba(0, 0, 0, 0.6);
  cursor: pointer;
}

.video-progress-filled {
  width: 0;
  background: orangered;
}

.video-player:hover .video-progress {
  height: 13px;
}
input[type="range"] {
  -webkit-appearance: none;
  background: transparent;
  margin: 0;
  width: 7%;
  padding: 0 10px;
  
}
input[type="range"]:focus {
  outline: none;
}
input[type="range"]::-webkit-slider-runnable-track {
  width: 5%;
  height: 10px;
  cursor: pointer;
  background: white;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  height: 10px;
  width: 13px;
  background: orangered;
  cursor: pointer;
}
#timeOut{
  font-family: monospace;
  font-size: 120%;
  padding: 18px;
  color: white;
  border: none;
  background: none;
}
#btnPlay,#btnPause,#volumeNone,#volumeLow,#volumeHigh {
  font-size: 200%;
  padding: 10px;
  color: white;
  border: none;
  background: none;
}
#btnPlay:hover,#btnPause:hover,#volumeNone:hover,#volumeLow:hover,#volumeHigh:hover {
  transition: all 0.1s ease;
    color: orangered;
}

const volume = document.querySelector('.volume');
const volumeNone = document.getElementById("volumeNone");
const volumeLow = document.getElementById("volumeLow");
const volumeHigh = document.getElementById("volumeHigh");
const myVideo = document.getElementById("myVideo");
const btnPlay = document.getElementById("btnPlay");
const btnPause = document.getElementById("btnPause");
btnPlay.addEventListener("click", vidPlay);
btnPause.addEventListener("click", vidPause);


volume.addEventListener('mousemove', (e)=> {
        myVideo.volume = e.target.value;
        if(myVideo.volume === 0){
          volumeNone.classList.remove("hidden");
          volumeLow.classList.add("hidden");
          volumeHigh.classList.add("hidden");
        }
        else if(myVideo.volume < .5 && myVideo.volume > .1){
          volumeNone.classList.add("hidden");
          volumeLow.classList.remove("hidden");
          volumeHigh.classList.add("hidden");
        }
        else if(myVideo.volume > .5) {
          volumeNone.classList.add("hidden");
          volumeLow.classList.add("hidden");
          volumeHigh.classList.remove("hidden");
        }
      })

function vidPlay() {
  btnPlay.classList.add("hidden");
  btnPause.classList.remove("hidden");
  myVideo.play();
}
function vidPause() {
  btnPlay.classList.remove("hidden");
  btnPause.classList.add("hidden");
  myVideo.pause();
}

CodePudding user response:

is there an easy fix to separate the volume icon from the volume slider?

- Simply removing the code

You can remove the code that makes the volume icon synchronized with the volume slider in the first place.

const volume = document.querySelector('.volume');
const volumeNone = document.getElementById("volumeNone");
const volumeLow = document.getElementById("volumeLow");
const volumeHigh = document.getElementById("volumeHigh");
const myVideo = document.getElementById("myVideo");
const btnPlay = document.getElementById("btnPlay");
const btnPause = document.getElementById("btnPause");
btnPlay.addEventListener("click", vidPlay);
btnPause.addEventListener("click", vidPause);


/* volume.addEventListener('mousemove', (e)=> {
        myVideo.volume = e.target.value;
        if(myVideo.volume === 0){
          volumeNone.classList.remove("hidden");
          volumeLow.classList.add("hidden");
          volumeHigh.classList.add("hidden");
        }
        else if(myVideo.volume < .5 && myVideo.volume > .1){
          volumeNone.classList.add("hidden");
          volumeLow.classList.remove("hidden");
          volumeHigh.classList.add("hidden");
        }
        else if(myVideo.volume > .5) {
          volumeNone.classList.add("hidden");
          volumeLow.classList.add("hidden");
          volumeHigh.classList.remove("hidden");
        }
      })
*/
function vidPlay() {
  btnPlay.classList.add("hidden");
  btnPause.classList.remove("hidden");
  myVideo.play();
}
function vidPause() {
  btnPlay.classList.remove("hidden");
  btnPause.classList.add("hidden");
  myVideo.pause();
}
.hidden {
    display: none;
}
.video-player {
  max-width: 100%;
  position: relative;
  overflow: hidden;
}
.player-controls {
  display: flex;
  position: absolute;
  bottom: 0;
  width: 100%;
  transform: translateY(100%) translateY(-5px);
  transition: 0.3s;
  flex-wrap: wrap;
  background: rgba(0, 0, 0, 0.6);
}
.video-player:hover .player-controls {
  transform: translateY(0);
}
.video-progress {
  position: relative;
  display: flex;
  width: 100%;
  height: 5px;
  transition: 0.3s;
  background: rgba(0, 0, 0, 0.6);
  cursor: pointer;
}

.video-progress-filled {
  width: 0;
  background: orangered;
}

.video-player:hover .video-progress {
  height: 13px;
}
input[type="range"] {
  -webkit-appearance: none;
  background: transparent;
  margin: 0;
  width: 7%;
  padding: 0 10px;
  
}
input[type="range"]:focus {
  outline: none;
}
input[type="range"]::-webkit-slider-runnable-track {
  width: 5%;
  height: 10px;
  cursor: pointer;
  background: white;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  height: 10px;
  width: 13px;
  background: orangered;
  cursor: pointer;
}
#timeOut{
  font-family: monospace;
  font-size: 120%;
  padding: 18px;
  color: white;
  border: none;
  background: none;
}
#btnPlay,#btnPause,#volumeNone,#volumeLow,#volumeHigh {
  font-size: 200%;
  padding: 10px;
  color: white;
  border: none;
  background: none;
}
#btnPlay:hover,#btnPause:hover,#volumeNone:hover,#volumeLow:hover,#volumeHigh:hover {
  transition: all 0.1s ease;
    color: orangered;
}
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <link href="style.css" rel="stylesheet" type="text/css" />
  <link
    rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
  />
</head>

<body>
<div >
  <video id="myVideo" poster="Poke_Ball.png">
  <source src="https://www.youtube.com/watch?v=Y3xgmGSnzlU" >    
  </video>
  <div >
      <div >
        <div ></div>
      </div>

      <button id="btnPlay"><i ></i></button>
      <button id="btnPause" ><i ></i></button>
      <button id="volumeNone" ><i ></i></button>
      <button id="volumeLow" ><i ></i></button>
      <button id="volumeHigh"><i ></i></button>
      <input type="range"  min="0" max="1" step="0.01" value=".5"/>
    </div>
</div>
  <script src="script.js"></script>
</body>

</html>

- Quick and easy fix instead of giving up on the idea

If the only reason you don't want to use this code is because it "feels janky", I fixed it by adding `min-width: 60px;` to `#btnPlay,#btnPause,#volumeNone,#volumeLow,#volumeHigh`. The problem was that the `volumeHigh`'s width was larger than `volumeLow` and `volumeNone`'s. fixing all the icon's width at a minimum of 60px solved the problem. `width: 60px` will also work.

const volume = document.querySelector('.volume');
const volumeNone = document.getElementById("volumeNone");
const volumeLow = document.getElementById("volumeLow");
const volumeHigh = document.getElementById("volumeHigh");
const myVideo = document.getElementById("myVideo");
const btnPlay = document.getElementById("btnPlay");
const btnPause = document.getElementById("btnPause");
btnPlay.addEventListener("click", vidPlay);
btnPause.addEventListener("click", vidPause);


 volume.addEventListener('mousemove', (e)=> {
        myVideo.volume = e.target.value;
        if(myVideo.volume === 0){
          volumeNone.classList.remove("hidden");
          volumeLow.classList.add("hidden");
          volumeHigh.classList.add("hidden");
        }
        else if(myVideo.volume < .5 && myVideo.volume > .1){
          volumeNone.classList.add("hidden");
          volumeLow.classList.remove("hidden");
          volumeHigh.classList.add("hidden");
        }
        else if(myVideo.volume > .5) {
          volumeNone.classList.add("hidden");
          volumeLow.classList.add("hidden");
          volumeHigh.classList.remove("hidden");
        }
      })

function vidPlay() {
  btnPlay.classList.add("hidden");
  btnPause.classList.remove("hidden");
  myVideo.play();
}
function vidPause() {
  btnPlay.classList.remove("hidden");
  btnPause.classList.add("hidden");
  myVideo.pause();
}
.hidden {
    display: none;
}
.video-player {
  max-width: 100%;
  position: relative;
  overflow: hidden;
}
.player-controls {
  display: flex;
  position: absolute;
  bottom: 0;
  width: 100%;
  transform: translateY(100%) translateY(-5px);
  transition: 0.3s;
  flex-wrap: wrap;
  background: rgba(0, 0, 0, 0.6);
}
.video-player:hover .player-controls {
  transform: translateY(0);
}
.video-progress {
  position: relative;
  display: flex;
  width: 100%;
  height: 5px;
  transition: 0.3s;
  background: rgba(0, 0, 0, 0.6);
  cursor: pointer;
}

.video-progress-filled {
  width: 0;
  background: orangered;
}

.video-player:hover .video-progress {
  height: 13px;
}
input[type="range"] {
  -webkit-appearance: none;
  background: transparent;
  margin: 0;
  width: 7%;
  padding: 0 10px;  
}
input[type="range"]:focus {
  outline: none;
}
input[type="range"]::-webkit-slider-runnable-track {
  width: 5%;
  height: 10px;
  cursor: pointer;
  background: white;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  height: 10px;
  width: 13px;
  background: orangered;
  cursor: pointer;
}
#timeOut{
  font-family: monospace;
  font-size: 120%;
  padding: 18px;
  color: white;
  border: none;
  background: none;
}
#btnPlay,#btnPause,#volumeNone,#volumeLow,#volumeHigh {
  font-size: 200%;
  padding: 10px;
  color: white;
  border: none;
  background: none;
  min-width: 60px; 
}
#btnPlay:hover,#btnPause:hover,#volumeNone:hover,#volumeLow:hover,#volumeHigh:hover {
  transition: all 0.1s ease;
    color: orangered;
}
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <link href="style.css" rel="stylesheet" type="text/css" />
  <link
    rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
  />
</head>

<body>
<div >
  <video id="myVideo" poster="Poke_Ball.png">
  <source src="https://www.youtube.com/watch?v=Y3xgmGSnzlU" >    
  </video>
  <div >
      <div >
        <div ></div>
      </div>

      <button id="btnPlay"><i ></i></button>
      <button id="btnPause" ><i ></i></button>
      <button id="volumeNone" ><i ></i></button>
      <button id="volumeLow" ><i ></i></button>
      <button id="volumeHigh"><i ></i></button>
      <input type="range"  min="0" max="1" step="0.01" value=".5"/>
    </div>
</div>
  <script src="script.js"></script>
</body>

</html>

CodePudding user response:

I'm not sure if this is different in a video player for whatever reason but when facing issues like that in the past I usually will wrap the icon in some kind of container that is big enough to accommodate the biggest icon. It needs to have either static dimensions or dimensions that are informed by something other than its contents.

Then you can either give it position relative and center the icons absolutely, or (and this is what I recommend) you can just use flexbox to center the icon.

Here is a Svelte Repl with an example. If you don't know svelte don't worry just know I'm switching between a 24x24 icon and a 34x34 icon and am using the button as the container. The styles are in a style tag at the bottom. https://svelte.dev/repl/34a316c3169248ce84b18972ab4953f5?version=3.47.0

  • Related