web-dev-qa-db-fra.com

"text-align: justifier;" éléments de bloc en ligne correctement?

Quelques autres questions ont déjà porté sur la meilleure façon d'appliquer text-align: justify pour que les éléments de bloc en ligne soient répartis de manière uniforme… par exemple, Comment est-ce que je justifie réellement * un * menu horizontal en HTML + CSS?

Toutefois, le navigateur attribue à l’élément 100% width qui "efface" la ligne des éléments inline-block sa propre ligne. Je n'arrive pas à comprendre comment supprimer cet espace vertical vide sans utiliser line-height: 0; sur l'élément parent.

Pour un exemple du problème, voir this violon

Pour ma solution qui utilise line-height: 0;, voir this violon

La solution que j'utilise nécessite qu'un nouveau line-height soit appliqué aux éléments enfants, mais tout line-height précédemment défini est perdu. Est-ce que quelqu'un est au courant d'une meilleure solution? Je souhaite éviter les tableaux afin que les éléments puissent se terminer lorsque c'est nécessaire, ainsi que la flexbox, car la prise en charge du navigateur n'existe pas encore. Je souhaite également éviter les flottants, car le nombre d'éléments espacés sera arbitraire.

50
thirdender

Mise à jour de la solution "Future" ci-dessous; toujours pas encore complètement supporté.

Solution de contournement actuelle (IE8 +, FF, Chrome testé)

Voir ce violon.

CSS pertinentes

_.prevNext {
    text-align: justify;
}

.prevNext a {
    display: inline-block;
    position: relative;
    top: 1.2em; /* your line-height */
}

.prevNext:before{
    content: '';
    display: block;
    width: 100%;
    margin-bottom: -1.2em; /* your line-height */
}

.prevNext:after {
    content: '';
    display: inline-block;
    width: 100%;
}
_

Explication

Le _display: block_ de l'élément _:before_ avec la marge inférieure négative tire les lignes de texte d'une hauteur, ce qui élimine la ligne supplémentaire, mais déplace le texte. Ensuite, avec les éléments _position: relative_ sur les éléments _inline-block_, le déplacement est neutralisé, mais sans rajouter la ligne supplémentaire.

Bien que les fichiers css ne puissent pas accéder directement à une "unité" _line-height_, l’utilisation de em dans les paramètres _margin-bottom_ et top convient facilement à tout _line-height_ donné comme un des valeurs de multiplicateur . Ainsi, _1.2_, _120%_ ou _1.2em_ sont tous égaux dans le calcul par rapport à _line-height_ , ce qui rend l'utilisation de em un bon choix ici, même si _line-height: 1.2_ est défini, puis _1.2em_ pour _margin-bottom_ et top va correspondre. Un bon codage pour normaliser l'apparence d'un site signifie qu'à un moment donné _line-height_ devrait être défini explicitement. Par conséquent, si l'une des méthodes de multiplication est utilisée, l'unité équivalente em donnera la même valeur que le _line-height_. Et si _line-height_ est défini sur une longueur non -em, telle que px, elle peut être définie à la place.

Avoir une variable ou un mixin utilisant un préprocesseur CSS tel que LESS ou SCSS pourrait aider à garder ces valeurs identiques au _line-height_ approprié, ou javascript pourrait être utilisé pour lire dynamiquement une telle variable, mais le _line-height_ devrait être connu dans le contexte de son utilisation, et les réglages appropriés effectués ici.

UPDATE pour le problème de texte minifié (sans espaces)

Le commentaire de Kubi a noté qu'une minification du code HTML qui supprime les espaces entre les éléments _<a>_ provoque l'échec de la justification . Un pseudo-espace dans la balise _<a>_ ne résout pas le problème (mais cela est prévu, car l'espace se passe dans l'élément _inline-block_), un _<wbr>_ ajouté entre les balises _<a>_ n’aide pas (probablement parce qu’une pause n’est pas nécessaire à la ligne suivante), donc si la minification est souhaitée, alors la solution est un code non codé en dur Caractère de fracture _&nbsp;_ - Les autres caractères d'espace tels que espace mince et en espace ne fonctionnaient pas (étonnamment).

À l'approche d'une solution propre pour l'avenir

ne solution dans laquelle webkit était en retard (à la date de la première écriture):

_.prevNext {
    text-align: justify;
    -moz-text-align-last: justify;
    -webkit-text-align-last: justify; /* not implemented yet, and will not be */
    text-align-last: justify; /* IE */
}
_

Cela fonctionne dans FF 12.0+ et IE8 + (buggy dans IE7).

Pour Webkit, à partir de la version 39 (du moins, il pourrait s’être glissé plus tôt), il le supporte sans l’extension _-webkit-_ mais uniquement si l’utilisateur a activé le fonctionnalités expérimentales (pouvant être effectuées à _chrome://flags/#enable-experimental-web-platform-features_). Selon les rumeurs, les versions 41 ou 42 devraient bénéficier d'un soutien total. Comme il n’est pas encore supporté de manière transparente par webkit, , il ne s’agit toujours que d’une solution partielle . Cependant, j'ai pensé que je devrais le poster car cela peut être utile pour certains.

86
ScottS

Considérer ce qui suit:

.prevNext {
    display: table;
    width: 100%
}

.prevNext a {
    display: table-cell;
    text-align: center
}

(Voir également le violon édité .) Est-ce ce que vous cherchez? L'avantage de cette technique est que vous pouvez ajouter plus d'éléments et ils seront tous automatiquement centrés. Pris en charge par tous les navigateurs Web modernes.

7
ACJ

Tout d'abord, j'aime bien l'approche du pseudo-element afin de conserver la sémantique du balisage. Je pense que vous devriez vous en tenir à l'approche globale. C'est bien mieux que de recourir à des tables, à des balises inutiles ou à des scripts superbes pour saisir les données de positionnement. 

Pour tout le monde a souligné à propos de text-align être hacky - allez! Il vaut mieux que le code HTML soit sémantique au détriment du CSS que l’inverse.

Donc, si j'ai bien compris, vous essayez d'obtenir cet effet de blocage en ligne justifié sans avoir à vous soucier de réinitialiser le line-height à chaque fois, n'est-ce pas? Je soutiens que vous ajoutez simplement

.prevNext *{
    line-height: 1.2;  /* or normal */
}

Ensuite, vous pouvez coder comme si de rien n'était. Voici la citation de Paul Irish sur le sélecteur * si vous vous inquiétez pour la performance:

"... vous n'êtes pas autorisé à vous soucier des performances de * sauf si vous concaténez tout votre javascript, le placez au bas de la liste, réduisez vos css et js, gzip tous vos actifs et compressez sans perte toutes vos images. Si nous obtenons plus de 90 scores de vitesse de page, il est trop tôt pour penser à l'optimisation du sélecteur. "

J'espère que cela t'aides!

-J Cole Morrison

4
J Cole Morrison

Tenter de text-align pour résoudre ce problème est plutôt compliqué. La propriété text-align est destinée à aligner le contenu en ligne d'un bloc (en particulier du texte). Elle n'est pas destinée à aligner des éléments html.

Je comprends que vous essayez d’éviter les flottements, mais à mon avis, les flotteurs sont le meilleur moyen d’accomplir ce que vous essayez de faire.

1
Michael Frederick

Comme indiqué par @Scotts, les éléments suivants ont été implémentés dans Chrome, sans la partie -webkit, ce que j'ai vraiment aimé, en particulier dans la mesure où nous devons nous débarrasser du -browser-specific-shǐt très bientôt. 

.prevNext {
    text-align: justify;
    -moz-text-align-last: justify;
    -webkit-text-align-last: justify; /* not implemented yet, and will not be */
    text-align-last: justify; /* IE + Chrome */
}

Note: Bien que toujours Safari et Opera ne le supporte pas encore (08-SEPT-16).

0
Mohd Abdul Mujib

Votre violon est terriblement spécifique. Il me semble que dans votre cas ce CSS fonctionnerait bien:

.prevNext {
    border: 1px solid #ccc;
    position: relative;
    height: 1.5em;
}

.prevNext a {
    display: block;
    position: absolute;
    top: 0;
}

.prevNext a:first-child {
    left: 0;
    text-align: left;
}
.prevNext a:last-child {
    right: 0;
    text-align: right;
}
​
0
artlung

Dans votre exemple, vous avez line-height:1.2, sans unité. Cela peut causer des problèmes. Si vous n'utilisez pas de bordures, vous pouvez donner au parent et aux enfants un line-height de 0.

Les autres options auxquelles je peux penser sont:

  1. Utilisez display:table sur le parent et display:table-cell sur les enfants pour simuler un comportement semblable à celui d'une table. Et vous alignez le premier élément à gauche et le dernier à droite. Voir ce violon .
  2. Utilisez javascript pour compter les enfants de la navigation, puis donnez-leur une largeur égale. par exemple. 4 enfants, 25% width chacun. Et alignez les premier et dernier éléments à gauche et à droite respectivement.
  3. Il existe un moyen de répartir les éléments de manière égale, mais il s'agit d'une méthode compliquée qui nécessite de placer soigneusement des espaces insécables dans le code HTML avec une marge négative et text-align:justify. Vous pouvez essayer de l'adapter à l'élément nav. Voir exemple ici .
0
Moin Zaman