Comment styliser l'entrée de la plage HTML5 pour avoir une couleur différente avant et après le curseur?

93

entrez la description de l'image ici

Je veux que le côté gauche soit vert et le côté droit soit gris. Comme illustré ci-dessus, ce serait PARFAIT. De préférence une solution CSS pure (il suffit de se soucier de WebKit).

Une telle chose est possible?

Shamoon
la source
Probablement, qu'avez-vous essayé? Postez votre code ici.
j08691

Réponses:

118

Solution CSS pure :

  • Chrome: masquez le débordement input[range]et remplissez tout l'espace laissé au pouce avec une couleur d'ombre.
  • IE: pas besoin de réinventer la roue:::-ms-fill-lower
  • Firefox pas besoin de réinventer la roue:::-moz-range-progress

/*Chrome*/
@media screen and (-webkit-min-device-pixel-ratio:0) {
    input[type='range'] {
      overflow: hidden;
      width: 80px;
      -webkit-appearance: none;
      background-color: #9a905d;
    }
    
    input[type='range']::-webkit-slider-runnable-track {
      height: 10px;
      -webkit-appearance: none;
      color: #13bba4;
      margin-top: -1px;
    }
    
    input[type='range']::-webkit-slider-thumb {
      width: 10px;
      -webkit-appearance: none;
      height: 10px;
      cursor: ew-resize;
      background: #434343;
      box-shadow: -80px 0 0 80px #43e5f7;
    }

}
/** FF*/
input[type="range"]::-moz-range-progress {
  background-color: #43e5f7; 
}
input[type="range"]::-moz-range-track {  
  background-color: #9a905d;
}
/* IE*/
input[type="range"]::-ms-fill-lower {
  background-color: #43e5f7; 
}
input[type="range"]::-ms-fill-upper {  
  background-color: #9a905d;
}
<input type="range"/>

deathangel908
la source
1
Salut deathangel908, belle solution. Je voudrais simplement améliorer la partie de l'ombre de la boîte: box-shadow: -80px 0 0px 80px # 43e5f7;
Filip Witkowski
32
Le problème avec cela dans Chrome est que si vous voulez que le pouce soit plus grand que la piste, alors l'ombre de la boîte chevauche la piste avec la hauteur du pouce. Existe-t-il un moyen de confiner la boîte-ombre à l'intérieur de la piste?
mharris7190
1
Cela ne fonctionne pas pour les entrées avec des largeurs basées sur un pourcentage. Quelqu'un a une solution de contournement pour cela?
Remi Sture
2
Une version CSS / JS fonctionnelle peut être trouvée ici: jsfiddle.net/remisture/esyvws3d
Remi Sture
3
@tenwest Wow, c'est horrible. Merci pour la mise à jour!
CodeF0x le
50

Bien que la réponse acceptée soit bonne en théorie, elle ignore le fait que le pouce ne peut alors pas être plus grand que la taille de la piste sans être coupé par le overflow: hidden. Voir cet exemple de la façon de gérer cela avec juste un tout petit peu de JS.

// .chrome styling Vanilla JS

document.getElementById("myinput").oninput = function() {
  this.style.background = 'linear-gradient(to right, #82CFD0 0%, #82CFD0 ' + this.value + '%, #fff ' + this.value + '%, white 100%)'
};
#myinput {
  background: linear-gradient(to right, #82CFD0 0%, #82CFD0 50%, #fff 50%, #fff 100%);
  border: solid 1px #82CFD0;
  border-radius: 8px;
  height: 7px;
  width: 356px;
  outline: none;
  transition: background 450ms ease-in;
  -webkit-appearance: none;
}
<div class="chrome">
  <input id="myinput" type="range" value="50" />
</div>

Dargue3
la source
pouvez-vous me suggérer quand j'ai ajouté max = 5 en HTML alors la couleur ne se remplit pas correctement
Husna
@Husna J'ai étendu cette réponse pour gérer également les attributs min max, j'espère que cela aidera.
htmn
1
@Husna Vous devez calculer le% comme une différence entre votre valeur max et min. Par exemple, si vous avez min: 0 et max: 10, vous devez utiliser, dans le JS :,+ this.value / (10-0)*100 +'%, #fff
Rosario Russo
4
@Rosario Russo Il vous suffit de répéter cette valeur dans la JS avec(this.value-this.min)/(this.max-this.min)*100
Silvan le
29

Oui c'est possible. Bien que je ne le recommande pas car il input rangen'est pas vraiment pris en charge correctement par tous les navigateurs, car un nouvel élément ajouté en HTML5 et HTML5 n'est qu'un brouillon (et le sera pour longtemps) donc aller jusqu'à la mise en forme, ce n'est peut-être pas le meilleur choix.

De plus, vous aurez également besoin d'un peu de JavaScript. J'ai pris la liberté d'utiliser la bibliothèque jQuery pour cela, à des fins de simplicité.

Ici vous allez: http://jsfiddle.net/JnrvG/1/ .

federico-t
la source
8
Ce n'était pas la question, de quoi ai-je besoin pour le faire par css, il ne doit y avoir moyen que de css.
Ipad du
10
Vous pouvez le faire fonctionner dans Chrome sans JS ( jsfiddle.net/1xg1j3tw ). Pour IE10 +, vous pouvez utiliser les pseudo éléments -ms-fill-lower et -ms-fill-upper.
Ales
1
@Ales Vous devriez mettre cela dans une réponse supplémentaire.
Luca Steeb
4
Changez en .change(pour on('input', func..que l'arrière-plan change lorsque l'utilisateur déplace le pouce et non pas simplement la souris.
Yami Odymel
10

Une petite mise à jour de celui-ci:

si vous utilisez ce qui suit, il se mettra à jour à la volée plutôt qu'au relâchement de la souris.

"change mousemove", fonction "

<script>
$('input[type="range"]').on("change mousemove", function () {
    var val = ($(this).val() - $(this).attr('min')) / ($(this).attr('max') - $(this).attr('min'));

    $(this).css('background-image',
                '-webkit-gradient(linear, left top, right top, '
                + 'color-stop(' + val + ', #2f466b), '
                + 'color-stop(' + val + ', #d3d3db)'
                + ')'
                );
});</script>
James Parker
la source
7

En vous basant sur la réponse de @ dargue3 , si vous voulez que le pouce soit plus grand que la piste, vous voulez profiter pleinement de l' <input type="range" />élément et passer à travers le navigateur, vous avez besoin de quelques lignes supplémentaires de JS et CSS.

Chrome / Mozilla vous pouvez utiliser la linear-gradienttechnique, mais vous devez régler le rapport sur la base min, max, les valueattributs mentionnés ici par @Attila O. . Vous devez vous assurer de ne pas l'appliquer sur Edge, sinon le pouce ne s'affiche pas. @Geoffrey Lalloué l' explique plus en détail ici .

Une autre chose à mentionner est que vous devez ajuster le rangeEl.style.height = "20px";sur IE / Older. En termes simples, c'est parce que dans ce cas "la hauteur n'est pas appliquée à la piste mais plutôt à toute l'entrée y compris le pouce". violon

/**
 * Sniffs for Older Edge or IE,
 * more info here:
 * https://stackoverflow.com/q/31721250/3528132
 */
function isOlderEdgeOrIE() {
  return (
    window.navigator.userAgent.indexOf("MSIE ") > -1 ||
    !!navigator.userAgent.match(/Trident.*rv\:11\./) ||
    window.navigator.userAgent.indexOf("Edge") > -1
  );
}

function valueTotalRatio(value, min, max) {
  return ((value - min) / (max - min)).toFixed(2);
}

function getLinearGradientCSS(ratio, leftColor, rightColor) {
  return [
    '-webkit-gradient(',
    'linear, ',
    'left top, ',
    'right top, ',
    'color-stop(' + ratio + ', ' + leftColor + '), ',
    'color-stop(' + ratio + ', ' + rightColor + ')',
    ')'
  ].join('');
}

function updateRangeEl(rangeEl) {
  var ratio = valueTotalRatio(rangeEl.value, rangeEl.min, rangeEl.max);

  rangeEl.style.backgroundImage = getLinearGradientCSS(ratio, '#919e4b', '#c5c5c5');
}

function initRangeEl() {
  var rangeEl = document.querySelector('input[type=range]');
  var textEl = document.querySelector('input[type=text]');

  /**
   * IE/Older Edge FIX
   * On IE/Older Edge the height of the <input type="range" />
   * is the whole element as oposed to Chrome/Moz
   * where the height is applied to the track.
   *
   */
  if (isOlderEdgeOrIE()) {
    rangeEl.style.height = "20px";
    // IE 11/10 fires change instead of input
    // https://stackoverflow.com/a/50887531/3528132
    rangeEl.addEventListener("change", function(e) {
      textEl.value = e.target.value;
    });
    rangeEl.addEventListener("input", function(e) {
      textEl.value = e.target.value;
    });
  } else {
    updateRangeEl(rangeEl);
    rangeEl.addEventListener("input", function(e) {
      updateRangeEl(e.target);
      textEl.value = e.target.value;
    });
  }
}

initRangeEl();
input[type="range"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  width: 300px;
  height: 5px;
  padding: 0;
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}


/*Chrome thumb*/

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  -moz-appearance: none;
  -webkit-border-radius: 5px;
  /*16x16px adjusted to be same as 14x14px on moz*/
  height: 16px;
  width: 16px;
  border-radius: 5px;
  background: #e7e7e7;
  border: 1px solid #c5c5c5;
}


/*Mozilla thumb*/

input[type="range"]::-moz-range-thumb {
  -webkit-appearance: none;
  -moz-appearance: none;
  -moz-border-radius: 5px;
  height: 14px;
  width: 14px;
  border-radius: 5px;
  background: #e7e7e7;
  border: 1px solid #c5c5c5;
}


/*IE & Edge input*/

input[type=range]::-ms-track {
  width: 300px;
  height: 6px;
  /*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */
  background: transparent;
  /*leave room for the larger thumb to overflow with a transparent border */
  border-color: transparent;
  border-width: 2px 0;
  /*remove default tick marks*/
  color: transparent;
}


/*IE & Edge thumb*/

input[type=range]::-ms-thumb {
  height: 14px;
  width: 14px;
  border-radius: 5px;
  background: #e7e7e7;
  border: 1px solid #c5c5c5;
}


/*IE & Edge left side*/

input[type=range]::-ms-fill-lower {
  background: #919e4b;
  border-radius: 2px;
}


/*IE & Edge right side*/

input[type=range]::-ms-fill-upper {
  background: #c5c5c5;
  border-radius: 2px;
}


/*IE disable tooltip*/

input[type=range]::-ms-tooltip {
  display: none;
}

input[type="text"] {
  border: none;
}
<input type="range" value="80" min="10" max="100" step="1" />
<input type="text" value="80" size="3" />

htmn
la source
5

La solution précédente acceptée ne fonctionne plus .

J'ai fini par coder une fonction simple qui enveloppe le rangedans un conteneur stylé en ajoutant la barre nécessaire avant le curseur. J'ai écrit cet exemple où il était facile de voir les deux couleurs «bleu» et «orange» définies dans le css, afin qu'elles puissent être rapidement modifiées.

fedeghe
la source
1

Si vous utilisez la première réponse , il y a un problème avec le pouce. En chrome, si vous voulez que le pouce soit plus grand que la piste , alors l'ombre de la boîte chevauche la piste avec la hauteur du pouce.

Récapitulez simplement toutes ces réponses et écrivez un curseur fonctionnant normalement avec un curseur plus grand: jsfiddle

const slider = document.getElementById("myinput")
const min = slider.min
const max = slider.max
const value = slider.value

slider.style.background = `linear-gradient(to right, red 0%, red ${(value-min)/(max-min)*100}%, #DEE2E6 ${(value-min)/(max-min)*100}%, #DEE2E6 100%)`

slider.oninput = function() {
  this.style.background = `linear-gradient(to right, red 0%, red ${(this.value-this.min)/(this.max-this.min)*100}%, #DEE2E6 ${(this.value-this.min)/(this.max-this.min)*100}%, #DEE2E6 100%)`
};
#myinput {
  border-radius: 8px;
  height: 4px;
  width: 150px;
  outline: none;
  -webkit-appearance: none;
}

input[type='range']::-webkit-slider-thumb {
  width: 6px;
  -webkit-appearance: none;
  height: 12px;
  background: black;
  border-radius: 2px;
}
<div class="chrome">
  <input id="myinput" type="range" min="0" value="25" max="200" />
</div>

abdigali
la source
0

Il est maintenant pris en charge avec des pseudo éléments dans chacun des WebKit, Firefox et IE. Mais, bien sûr, c'est différent dans chacun d'eux. : (

Consultez les réponses à cette question et / ou recherchez un CodePen intitulé prettify <input type=range> #101pour certaines solutions.

Wilson F
la source
-5
input type="range" min="0" max="50" value="0"  style="margin-left: 6%;width: 88%;background-color: whitesmoke;"

le code ci-dessus change le style d'entrée de la plage .....

Krish
la source
Fonctionne dans FireFox 57 mais pas Opera 49 ni Safari 11 - pire, rien ne prend en charge la couleur de premier plan.
devon