50 votes

Existe-t-il un javascript multi-navigateur pour faire fonctionner les unités vh et vw ?

Note : Ok, pendant que je rédigeais cette question, je suis tombé sur este question qui suggère d'utiliser @media query mais on lui a demandé de revenir en 2011...

Comme vous le savez, CSS3 introduit de nouvelles Unités de longueur en pourcentage de la fenêtre de visualisation , vh y vw Ma question est donc la suivante : existe-t-il une alternative JavaScript/jQuery pour cela ? De plus, à part l'utiliser pour la taille des polices, est-il possible de l'utiliser pour dimensionner des éléments ? Par exemple

div {
   height: 6vh;
   width: 20vh;  /* Note am using vh for both, do I need to use vw for width here? */
}

0 votes

Ce qui s'en rapproche le plus, c'est un polyfill pour l'interface utilisateur de l'UE. rem unités -- github.com/chuckcarpenter/REM-unit-polyfill . Je n'ai pas pu en trouver un pour vh / vw mais étant donné que le rem il en existe un, j'imagine que c'est possible.

0 votes

Et celui-là pourrait être utile à regarder aussi -- github.com/heygrady/Units -- Je vois qu'il mentionne vh / vw dans la documentation. Je ne pense pas que ce soit le polyfill direct que vous voulez cependant.

3 votes

Voici une question de 10.9k éditée par une de 19.2k, répondue par une de 15.4k aaaaah

16voto

elclanrs Points 40467

Mise à jour 5 : .css(propriété) fixe Des plugins comme fancyBox utiliser .css('margin-right') pour récupérer la marge droite d'un élément et .css('margin-right', '12px') pour définir la marge droite d'un élément. Ceci était cassé, car il n'y avait pas de vérification si props est une chaîne de caractères et s'il y a plusieurs arguments donnés. Je l'ai corrigé en vérifiant si props est une chaîne de caractères. Si c'est le cas et qu'il y a plusieurs arguments, arguments est réécrit en un objet, sinon parseProps( $.extend( {}, props ) ) n'est pas utilisé.

Mise à jour 4 : Plugin pour les mises en page réactives https://github.com/elclanrs/jquery.columns (en cours de réalisation)

J'ai fait un (long) essai. Tout d'abord, voici l'exemple CSS : http://jsbin.com/orajac/1/edit#css . (redimensionner le panneau de sortie). Notez que le font-size ne fonctionne pas avec les unités d'affichage, du moins sur la dernière version de Chrome.

Et voici ma tentative de faire cela avec jQuery. La démo de jQuery qui fonctionne aussi avec la police est à http://jsbin.com/izosuy/1/edit#javascript . Je ne l'ai pas testé de manière approfondie mais cela semble fonctionner avec la plupart des propriétés puisqu'il s'agit simplement de convertir les valeurs en pixel et ensuite d'appeler le plugin sur window.resize il ne cesse de se mettre à jour.

Mise à jour : Code mis à jour pour fonctionner avec de nombreux navigateurs. Testez localement si vous utilisez autre chose que Chrome car jsBin se comporte un peu bizarrement avec window.resize .

Mise à jour 2 : Élargir le champ d'application de la norme css méthode.

Mise à jour 3 : Gestion de l'événement window.resize à l'intérieur du plugin, de sorte que l'intégration est maintenant transparente.

L'essentiel (à tester localement) : https://gist.github.com/4341016

/*
 * CSS viewport units with jQuery
 * http://www.w3.org/TR/css3-values/#viewport-relative-lengths
 */
;(function( $, window ){

  var $win = $(window)
    , _css = $.fn.css;

  function viewportToPixel( val ) {
    var percent = val.match(/[\d.]+/)[0] / 100
      , unit = val.match(/[vwh]+/)[0];
    return (unit == 'vh' ? $win.height() : $win.width()) * percent +'px';
  }

  function parseProps( props ) {
    var p, prop;
    for ( p in props ) {
      prop = props[ p ];
      if ( /[vwh]$/.test( prop ) ) {
        props[ p ] = viewportToPixel( prop );
      }
    }
    return props;
  }

  $.fn.css = function( props ) {
    var self = this
      , originalArguments = arguments
      , update = function() {
          if ( typeof props === 'string' || props instanceof String ) {
            if (originalArguments.length > 1) {
              var argumentsObject = {};
              argumentsObject[originalArguments[0]] = originalArguments[1];
              return _css.call(self, parseProps($.extend({}, argumentsObject)));
            } else {
              return _css.call( self, props );
            }
          } else {
            return _css.call( self, parseProps( $.extend( {}, props ) ) );
          }
        };
    $win.resize( update ).resize();
    return update();
  };

}( jQuery, window ));

// Usage:
$('div').css({
  height: '50vh',
  width: '50vw',
  marginTop: '25vh',
  marginLeft: '25vw',
  fontSize: '10vw'
});

0 votes

Cela fonctionne bien sur chrome 22, mais échoue sur 17.0.1 :) mais bel essai +1...je voulais un cross-browser, oui je peux laisser IE7,8 pour sûr...mais au moins ff, chrome, opera(ne fonctionne pas, bien), ie9/10

0 votes

@Mr.Alien : C'était la ligne prop = viewportToPixel( prop ) le problème. J'ai changé pour prop[p] = viewportToPixel( prop ) et cela fonctionne bien maintenant dans tous les navigateurs. Testez-le ! jsbin.com/ugefub/1/edit#javascript

0 votes

@Mr.Alien : Aussi jsBin fait des choses bizarres avec window.resize dans tous les navigateurs, sauf Chrome. Essayez-le localement, il fonctionne bien dans FF, Opera et Chrome AFAIK. Voici un résumé gist.github.com/4341016

14voto

Je suis confronté à ce problème avec le navigateur stock d'Android 4.3 (ne prend pas en charge vw, vh, etc.). La façon dont j'ai résolu le problème est d'utiliser 'rem' comme unité de taille de police et de changer dynamiquement la taille de police de < html > avec javascript.

function viewport() {
    var e = window, a = 'inner';
    if (!('innerWidth' in window )) {
        a = 'client';
        e = document.documentElement || document.body;
    }
    return { width : e[ a+'Width' ] , height : e[ a+'Height' ] };
}
jQuery(window).resize(function(){
    var vw = (viewport().width/100);
    jQuery('html').css({
        'font-size' : vw + 'px'
    });
});

et dans votre css, vous pouvez utiliser 'rem' au lieu de px, ems, etc.

.element {
    font-size: 2.5rem; /* this is equivalent to 2.5vw */
}

Voici une démo du code : http://jsfiddle.net/4ut3e/

4 votes

À propos de rem s, il existe certaines versions d'Android (je ne me souviens plus lesquelles) qui ont une taille de police minimale (dans mon cas, c'était 8px). Ainsi, si la taille de la police de votre racine est inférieure à 8px, elle sera automatiquement arrondie à 8px, ce qui risque de casser votre mise en page.

7voto

Konrad Points 43

J'ai écrit une petite aide pour gérer ce problème. Il est supporté par tous les principaux navigateurs et utilise jQuery.
C'est ici :

SupportVhVw.js

function SupportVhVw() {

    this.setVh = function(name, vh) {

        jQuery(window).resize( function(event) {
            scaleVh(name, vh);
        });

        scaleVh(name, vh);
    }

    this.setVw = function(name, vw) {

        jQuery(window).resize( function(event) {
            scaleVw(name, vw);
        });

        scaleVw(name, vw);
    }

    var scaleVw = function(name, vw) {

        var scrWidth = jQuery(document).width();
        var px = (scrWidth * vw) / 100;
        var fontSize = jQuery(name).css('font-size', px + "px");
    }

    var scaleVh = function(name, vh) {

        var scrHeight = jQuery(document).height();

        var px = (scrHeight * vh) / 100;
        var fontSize = jQuery(name).css('font-size', px + "px");
    }
};

Exemple simple d'utilisation en HTML :

<head>

    <title>Example</title>

    <!-- Import all libraries -->
    <script type="text/javascript" src="js/libs/jquery-1.10.2.min.js"></script>
    <script type="text/javascript" src="js/libs/SupportVhVw.js"></script>

</head>
<body>

                    <div id="textOne">Example text one (vh5)</div>
                    <div id="textTwo">Example text two (vw3)</div>
                    <div id="textThree" class="textMain">Example text three (vh4)</div>
                    <div id="textFour" class="textMain">Example text four (vh4)</div>

            <script type="text/javascript">

                    // Init object
                    var supportVhVw = new SupportVhVw();

                    // Scale all texts
                    supportVhVw.setVh("#textOne", 5);
                    supportVhVw.setVw("#textTwo", 3);
                    supportVhVw.setVh(".textMain", 4);

            </script>

</body>

Il est disponible sur GitHub :
https://github.com/kgadzinowski/Support-Css-Vh-Vw

Exemple sur JSFiddle : http://jsfiddle.net/5MMWJ/2/

3 votes

Pourquoi manipulez-vous attachEvent et addEventListener ET importez-vous jQuery ?

0 votes

C'est une petite erreur qui n'a rien à voir avec le comportement correct du code. Je ne vois pas de raison de voter contre un code qui fonctionne bien et qui est facile à utiliser :/ J'ai corrigé ma réponse.

1 votes

Je n'ai pas rétrogradé, j'ai juste posé la question. Il semble idiot de traiter ces cas séparément et d'utiliser ensuite jQuery à d'autres endroits.

4voto

RobW Points 2202

Vminpoly est le seul polyfill que je connaisse - il est en cours de développement mais fonctionne à ce jour. Il y a des polyfills statiques dans le cadre de l'application Colonnes Jquery y -sans préfixe également des projets.

0voto

João Cunha Points 2741

J'ai publié une petite lib qui facilite la fenêtre d'affichage-dimensions relatives à l'utilisation. Gardez à l'esprit ce n'est pas un polyfill, donc il faut que vous appliquez les classes sur les éléments que vous souhaitez redimensionner. Par exemple, <div class="vh10 vw30">hello</div> remplira 10% de la hauteur et de 30% de la largeur.

Check it out: https://github.com/joaocunha/v-unit

0 votes

Le seul problème est qu'il ne prend pas en charge les tailles de police, les bordures, le rembourrage, etc.

0 votes

Oui, il y a une question ouverte pour l'ajouter : github.com/joaocunha/v-unit/issues/7

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X