web-dev-qa-db-fra.com

Responsive INLINE SVG - le contenu du svg doit remplir la largeur du parent

OBJECTIF:

J'essaye d'obtenir un INLINE SVG élément pour remplir toute la largeur disponible de l'élément parent. Je peux obtenir le même effet facilement en utilisant une balise img et object pour référencer le fichier svg, mais je veux utiliser inline svg parce que j'anime les éléments internes svg avec javascript.

PROBLÈME:

Je peux y arriver dans Firefox et avec quelques ajustements également dans Chrome, mais safari et IE9 & IE10 ne joueront pas la balle.

  • Le contenu interne de svg ne remplit pas toujours l'élément svg dans toutes les largeurs d'écran
  • webkit ajoute un remplissage/hauteur mystérieux (dans cet exemple, le remplissage est dans l'élément svg) La hauteur de l'élément SVG doit être automatique et encapsuler le contenu svg interne.

QUESTION PRINCIPALE:

Existe-t-il une solution multi-navigateur pour le SVG INLINE réactif: Voir l'exemple dans IE9 & 10 et -webkit-Safari et notez la hauteur supplémentaire non requise dans l'élément SVG (la couleur cyan).

http://jsfiddle.net/David_Knowles/9tUAd/

<div class="block">stuff</div> 
<div class="wrap">
    <svg version="1.1" baseProfile="basic" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 550 350" xml:space="preserve" preserveAspectRatio="xMinYMin meet">

        <rect x="0" y="0" width="550" height="350"/>
        <polyline points="0,0 0,350 550,350"/>
        <text x="0" y="50%" fill="#ffffff" stroke="none" width="100%">The text</text>
    </svg>
</div>
<div class="block">stuff</div> 
32
Timidfriendly

Le premier problème est que vous définissez votre .svg-wrap div à 100% de hauteur. 100% de quoi? Dans ce cas, l'élément parent de cette div est l'élément body. Lorsque vous avez du contenu au niveau du bloc qui correspond à 100% de la hauteur du corps et d'autres éléments intégrés, vous aurez toujours une barre de défilement verticale. car vous aurez toujours un contenu à 100% + votre .stuff éléments. Tout comme une astuce générale, un débordement constant comme celui-ci devrait être le signe que quelque chose est bancal dans votre CSS.

En continuant dans le DOM, la déclaration de hauteur à 100% sur votre élément svg force le svg à se développer dans le wrapper trop haut. Et c'est une autre partie du coupable.

La solution que j'utilise implique ratios intrinsèques . CSS comme ceci:

.svg-wrap {
    background-color:red;
    height:0;
    padding-top:63.63%; /* 350px/550px */
    position: relative;
}

svg {
    background-color: cyan;
    height: 100%;
    display:block;
    width: 100%;
    position: absolute;
    top:0;
    left:0;
}

http://jsfiddle.net/pcEjd/

Testé dans la dernière version, FF, Chrome, Safari, (mais pas IE).

Les inconvénients de cette approche sont les suivants:

a) vous devez précalculer les ratios pour toutes vos boîtes, ou écrire un script qui le fasse. Pas mal.

b) vous ne pouvez pas utiliser border-box globalement avec le sélecteur d'étoiles, ou si vous avez besoin de redéfinir le dimensionnement de la boîte à content-box pour vos conteneurs svg. Faisable.

En remarque, ce n'est évidemment pas ainsi que les choses sont censées fonctionner. Les navigateurs doivent être assez intelligents pour regarder l'attribut viewbox SVG pour obtenir les proportions, calculer la largeur calculée (après toutes les limites maxWidth), puis calculer la hauteur.

Mais cela ne fonctionne pas actuellement de cette façon. Il y a un autre bug bizarre dans Chrome où l'ajout de max-width:100% au svg crée une situation où le svg est toujours dimensionné à la plus petite taille rendue. Essayez de charger ce violon dans Chrome:

http://jsfiddle.net/ynmey/1/

Et vous ne verrez aucun SVG du tout! Bizarre. Encore plus étrange, désactivez le max-width déclaration dans Dev Tools, puis commencez à jouer avec la largeur de la fenêtre "résultat" dans jsfiddle. Prenez-le légèrement plus étroit, puis plus large, puis plus étroit, puis plus large. Notez qu'une fois que le svg est plus petit, il ne se redimensionne pas lorsque la fenêtre s'agrandit!

Ceci est important à noter car:

 * {max-width:100%}

est une approche de conception réactive commune (et totalement légitime), et elle fait actuellement des ravages avec SVG dans Blink. Donc, respectez les ratios intrinsèques pour l'instant.

23
Ben

Le type d'affichage par défaut pour en ligne les éléments SVG est display: inline;. Cela signifie que l'élément SVG est placé sur la ligne de base typographique de son parent et est aligné en conséquence. Il y a toujours un espace sous la ligne de base pour permettre les bits pendants de caractères comme g et j et autres.

Solution facile: svg { display: block;} ou svg { display: inline-block; vertical-align: top; }.

7
jvhellemond

J'ai réussi à obtenir des résultats cohérents dans les navigateurs Webkit/Gecko en définissant une valeur height autre que auto ou 0. Dans mon exemple, j'utilise 1%, mais d'après ce que je peux dire, cela pourrait être n'importe quoi. D'une manière ou d'une autre, cela résout la hauteur incorrecte dans Webkit (d'après mes tests, je pense que auto définit incorrectement la hauteur SVG sur 100% hauteur de la fenêtre).

Je n'ai pas encore testé cela en IE. Veuillez me faire savoir si cela fonctionne.

http://jsfiddle.net/yXeru/

3
daviestar

Je ne suis pas tout à fait sûr de l'effet que vous essayez d'obtenir, mais je pense que vous cherchez peut-être pour keepAspectRatio = "xMinYMin slice"

2
Michael Mullany

Après beaucoup de tripotage, le navigateur moderne et solution compatible IE11 que j'ai utilisé se compose de deux parties:

  1. Spécifiez à la fois viewBox et preserveAspectRatio="xMinYMin meet" dans la balise racine svg.
  2. Utilisez les requêtes multimédia css pour donner à votre élément svg une hauteur en vw unités pour chaque mise en page.

bonne chance!

0
ryanrain