Question Mise à l'échelle des polices en fonction de la largeur du conteneur


J'ai du mal à comprendre la taille des polices.

J'ai actuellement ce site avec un corps font-size de 100%. 100% de quoi? Cela semble calculer à 16px.

J'avais l'impression que 100% se réfèrerait en quelque sorte à la taille de la fenêtre du navigateur, mais apparemment pas parce que c'est toujours 16px si la fenêtre est redimensionnée à une largeur mobile ou un bureau à écran large plein écran.

Comment puis-je faire le texte sur l'échelle de mon site par rapport à son conteneur? J'ai essayé d'utiliser em mais cela ne change pas non plus.

Mon raisonnement est que des choses comme mon menu sont écrasées lorsque vous redimensionnez, donc je dois réduire le px font-size de .menuItem entre autres éléments en relation avec la largeur du conteneur. (Par exemple, dans le menu sur un grand bureau, 22px fonctionne parfaitement.Rendez-vous à la largeur de la tablette et 16px est plus approprié.)

Je sais que je peux ajouter des points d'arrêt, mais je veux vraiment que le texte évolue aussi bien que d'avoir des points d'arrêt supplémentaires, sinon je finirai avec des centaines de points d'arrêt pour chaque 100px de largeur pour contrôler le texte.


808
2018-04-17 09:37


origine


Réponses:


EDIT: Si le conteneur n'est pas le corps CSS Tricks couvre toutes vos options ici: https://css-tricks.com/fitting-text-to-a-container/

Si le conteneur est le corps, ce que vous cherchez est Viewport-pourcentages:

le viewport-pourcentages sont relatifs à la taille de la bloc contenant initial. Lorsque la hauteur ou la largeur du bloc conteneur initial est modifiée, elles sont mises à l'échelle en conséquence. Toutefois, lorsque la valeur du dépassement sur l'élément racine est automatique, toutes les barres de défilement sont supposées ne pas exister.

Les valeurs sont:

  • vw (% de la largeur de la fenêtre)
  • vh (% de la hauteur de la fenêtre)
  • vi (1% de la taille de la fenêtre dans la direction de l'axe en-ligne de l'élément racine)
  • vb (1% de la taille de la fenêtre dans la direction de l'axe de bloc de l'élément racine)
  • vmin (le plus petit de vw ou vh)
  • vmax (le plus grand ou vw ou vh)

1 v * est égal à 1% du bloc conteneur initial.

l'utiliser ressemble à ceci:

p {
    font-size: 4vw;
}

Comme vous pouvez le constater, lorsque la largeur de la fenêtre augmente, la taille de la police augmente également, sans avoir besoin d'utiliser les requêtes de média.

Ces valeurs sont une unité de dimensionnement, tout comme px ou emIls peuvent donc être utilisés pour dimensionner d'autres éléments, tels que la largeur, la marge ou le remplissage.

La prise en charge du navigateur est assez bonne, mais vous aurez probablement besoin d'un système de secours, tel que:

p {
    font-size: 16px; 
    font-size: 4vw;
}

Consultez les statistiques de support: http://caniuse.com/#feat=viewport-units.

Jetez aussi un coup d'œil sur CSS-Tricks pour un look plus large: http://css-tricks.com/viewport-sized-typography/

Voici un bon article sur la définition des tailles min / max et un meilleur contrôle des tailles: http://madebymike.com.au/writing/precise-control-responsive-typography/

Et voici un article sur la définition de votre taille en utilisant calc () pour que le texte remplisse la fenêtre: http://codepen.io/CrocoDillon/pen/fBJxu

Aussi, s'il vous plaît voir cet article, qui utilise une technique surnommée «leader fondu» pour ajuster la hauteur de la ligne ainsi. https://css-tricks.com/molten-leading-css/


1172
2017-11-06 14:40



Mais que faire si le conteneur n'est pas la fenêtre (corps)?

Cette question est posée dans le commentaire par Alex sous la réponse acceptée.

Ce fait ne veut pas dire vw ne peut pas être utilisé dans une certaine mesure pour la taille de ce conteneur. Maintenant, pour voir toute variation, il faut supposer que le conteneur est d'une certaine manière flexible. Que ce soit par un pourcentage direct width ou en étant 100% moins les marges. Le point devient "discutable" si le conteneur est toujours configuré pour, disons, 200px large - alors juste définir un font-size cela fonctionne pour cette largeur.

Exemple 1

Avec un conteneur de largeur flexible, cependant, il faut se rendre compte que d'une certaine façon le conteneur est toujours être dimensionné hors de la vue. En tant que tel, il s'agit d'ajuster un vw paramètre basé sur cette différence de taille de pourcentage à la fenêtre, ce qui signifie prendre en compte le dimensionnement des enveloppes parent. Prenons cet exemple:

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       So if the container is 50% of viewport (as here)
       then factor that into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 2.5vw (5 * .5 [i.e. 50%])
    */
    font-size: 2.5vw; 
}

En supposant ici le div est un enfant de body, c'est 50% de ça 100% width, qui est la taille de la fenêtre dans ce cas de base. Fondamentalement, vous voulez définir un vw ça va te sembler bien. Comme vous pouvez le voir dans mon commentaire dans la css ci-dessus, vous pouvez "y réfléchir" mathématiquement par rapport à la taille de la fenêtre, mais vous ne le faites pas avoir besoin pour faire ça. Le texte va "fléchir" avec le conteneur, car le conteneur est en train de fléchir avec le redimensionnement de la fenêtre. METTRE À JOUR: Voici un exemple de deux récipients de tailles différentes.

Exemple 2

Vous pouvez aider à garantir le dimensionnement de la fenêtre en forçant le calcul en fonction de cela. Considérez cet exemple:

html {width: 100%;} /* force html to be viewport width */
body {width: 150%; } /* overflow the body */

div {
    width: 50%;
    border: 1px solid black;
    margin: 20px;
    font-size: 16px;
    /* 100 = viewport width, as 1vw = 1/100th of that
       Here, the body is 200% of viewport, but the container is 50% 
       of viewport, so both parents factor  into how you want it to size.
       Let's say you like 5vw if it were the whole width,
       then for this container, size it at 3.75vw 
       (5 * 1.5 [i.e. 150%]) * .5 [i.e. 50%]
    */
    font-size: 3.75vw; 
}

Le dimensionnement est toujours basé sur viewport, mais est essentiellement mis en place en fonction de la taille du conteneur lui-même.

Le dimensionnement du conteneur devrait-il changer de façon dynamique ...

Si le dimensionnement de l'élément conteneur a fini par changer dynamiquement sa relation de pourcentage soit via @media points de rupture ou via javascript, alors quelle que soit la «cible» de base aurait besoin de recalculer pour maintenir la même «relation» pour la taille du texte.

Prenons l'exemple n ° 1 ci-dessus. Si la div a été commuté à 25% largeur par soit @media ou javascript, puis en même temps, le font-size aurait besoin d'ajuster soit dans la requête des médias ou par javascript au nouveau calcul de 5vw * .25 = 1.25. Cela mettrait la taille du texte à la même taille qu'il aurait eu la «largeur» de l'original 50% La taille des conteneurs a été réduite de moitié par rapport à la taille de la fenêtre, mais elle a maintenant été réduite en raison d'un changement dans le calcul de son propre pourcentage.

Un défi

Avec le CSS3 calc() fonction en cours d'utilisation, il deviendrait difficile d'ajuster dynamiquement, car cette fonction ne fonctionne pas pour font-sizefins à ce moment. Vous ne pouvez donc pas faire un ajustement CSS3 pur si votre largeur change calc(). Bien sûr, un ajustement mineur de la largeur pour les marges peut ne pas être suffisant pour justifier une modification font-size, donc ça peut ne pas avoir d'importance.


249
2017-11-06 16:56



Ce que je fais dans un de mes projets est un "mélange" entre vw et vh pour ajuster la taille de la police à mes besoins, par exemple:

font-size: calc(3vw + 3vh);

Je sais que cela ne répond pas à la question de l'op, mais peut-être que cela peut être une solution pour quelqu'un d'autre.


21
2018-03-11 08:30



Il y a une grande philosophie pour ce problème. La chose la plus facile à faire serait de donner une certaine taille de police au corps (je recommande 10), et alors tous les autres éléments auraient leur police en em ou rem. Je vais vous donner et donner un exemple pour comprendre ces unités. Em est toujours par rapport à son parent

body{font-size:10px;}
.menu{font-size:2em;} /* that means 2*10px = 20px */
.menu li{font-size:1.5em;} /* that means 1.5*20px = 30px */

Rem est toujours relatif au corps

body{font-size:10px;}
.menu{font-size:2rem;} /* that means 2*10px = 20px */
.menu li{font-size:1.5rem;} /* that means 1.5*10px = 15px */

Et que vous pourriez créer un script qui modifierait la taille de police par rapport à la largeur de votre conteneur. Mais ce n'est pas ce que je recommanderais. Parce que dans un conteneur de 900px largeur par exemple, vous auriez un p élément avec 12px font-size, disons. Et sur votre idée qui deviendrait sur 300px largeur conteneur à 4px taille de police. Il doit y avoir une limite inférieure. Une autre solution serait avec les requêtes médias, de sorte que vous pouvez définir la police pour différentes largeurs.

Mais les solutions que je recommande est d'utiliser une bibliothèque javascript qui vous aide avec cela. Et fittext.js que j'ai trouvé jusqu'ici.


20
2017-11-11 10:01



Solution avec SVG:

<div style="width: 60px;">  
  <svg width="100%" height="100%" viewBox="0 -200 1000 300"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <text font-size="300" fill="black">Text</text>
  </svg>
</div>

https://jsfiddle.net/qc8ht5eb/


19
2018-06-18 16:47



Mise à jour parce que j'ai eu un vote négatif.

Voici la fonction:

document.body.setScaledFont = function(f) {
  var s = this.offsetWidth, fs = s * f;
  this.style.fontSize = fs + '%';
  return this
};

Ensuite, convertissez toutes les tailles de police de vos éléments enfant en em ou%.

Puis ajoutez quelque chose comme ceci à votre code pour définir la taille de police de base.

document.body.setScaledFont(0.35);
window.onresize = function() {
    document.body.setScaledFont(0.35);
}

http://jsfiddle.net/0tpvccjt/


18
2018-01-07 09:43



Cela peut ne pas être très pratique, mais si vous voulez que la police soit une fonction directe du parent, sans avoir de JS qui écoute / boucle (intervalle) pour lire la taille de la div / page, il y a un moyen de le faire. Iframes. Tout ce qui se trouve dans l'iframe considérera la taille de l'iframe comme la taille de la fenêtre. Donc, l'astuce consiste simplement à créer un iframe dont la largeur est la largeur maximale que vous voulez que votre texte soit, et dont la hauteur est égale à la hauteur maximale * le ratio d'aspect du texte particulier.

Mis à part la limitation selon laquelle les unités viewport ne peuvent pas venir aussi des unités parents latérales pour le texte (comme dans, ayant la taille% comme tout le monde), les unités viewport fournissent un outil très puissant: pouvoir obtenir la dimension min / max . Vous ne pouvez pas faire cela ailleurs - vous ne pouvez pas dire ... faire la hauteur de cette div soit la largeur du parent * quelque chose.

Cela étant dit, l'astuce consiste à utiliser vmin, et à définir la taille iframe pour que [fraction] * hauteur totale soit une bonne taille de police quand la hauteur est la dimension limite, et [fraction] * largeur totale quand la largeur est la dimension limitante. C'est pourquoi le haut doit être un produit de la largeur et du rapport d'aspect.

pour mon exemple particulier, vous avez

.main iframe{
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: calc(3.5 * 100%);
  background: rgba(0,0,0,0);
  border-style: none;
  transform: translate3d(-50%,-50%,0);
}

Le petit ennui avec cette méthode est que vous devez définir manuellement le CSS de l'iframe. Si vous attachez le fichier CSS entier, cela prendrait beaucoup de bande passante pour de nombreuses zones de texte. Donc, ce que je fais est d'attacher la règle que je veux directement à partir de mon CSS.

var rule = document.styleSheets[1].rules[4];
var iDoc = document.querySelector('iframe').contentDocument;
iDoc.styleSheets[0].insertRule(rule.cssText); 

Vous pouvez écrire une petite fonction qui obtient la règle CSS / toutes les règles CSS qui affecteraient la zone de texte.

Je ne peux pas penser à une autre façon de le faire sans avoir du vélo / écoute JS. La vraie solution serait que les navigateurs fournissent un moyen de mettre à l'échelle le texte en fonction du conteneur parent ET de fournir également la même fonctionnalité de type vmin / vmax.

JS violon: https://jsfiddle.net/0jr7rrgm/3/ (cliquez une fois pour verrouiller le carré rouge à la souris, cliquez à nouveau pour le relâcher)

La plupart des JS dans le violon est juste ma fonction de cliquer-glisser personnalisé


12
2018-04-12 19:22