Je pensais que je connaissais bien le CSS, mais je devais expliquer quelque chose à quelqu'un tout à l'heure et j'ai trouvé que je ne pouvais pas.
Ma question se résume essentiellement à: pourquoi vertical-align:baseline
Est-il ignoré alors qu'il y a d'autres alignements sur la même ligne?
Exemple: si la deuxième travée a vertical-align:bottom
, L'alignement vertical de la première travée est ignoré s'il s'agit de baseline
; il se comporte comme s'il avait bottom
aussi.
span:first-child {vertical-align:baseline}
span:last-child {font-size:3em; vertical-align:bottom;}
<p>
<span>one</span> <span>two</span>
</p>
Alors que si toutes les plages ont un alignement vertical autre que baseline
, ou, si elles sont toutes baseline
, elles se comportent comme prévu.
span:first-child {vertical-align:top}
span:last-child {font-size:3em; vertical-align:bottom;}
<p>
<span>one</span> <span>two</span>
</p>
span:first-child {vertical-align:baseline}
span:last-child {font-size:3em; vertical-align:baseline;}
<p>
<span>one</span> <span>two</span>
</p>
S'il s'agit d'un comportement normal, pourquoi n'est-il décrit nulle part? Je n'ai trouvé aucune source qui dit que la ligne de base et le haut/bas interfèrent l'un avec l'autre de cette manière.
vertical-align
est utilisé pour aligner éléments de niveau en ligne . Ce sont des éléments dont la propriété display
est évaluée à:
inline
inline-block
inline-table
(Non pris en compte dans cette réponse)Les éléments de niveau en ligne sont disposés côte à côte en lignes. Une fois qu'il y a plus d'éléments qu'il n'y en a dans la ligne actuelle, une nouvelle ligne est créée en dessous. Toutes ces lignes ont une boîte de ligne dite , qui renferme tout le contenu de sa ligne. Un contenu de taille différente signifie des boîtes de ligne de hauteur différente.
Dans l'illustration suivante, les cases supérieure et inférieure des lignes sont indiquées par des lignes rouges.
À l'intérieur de ces zones de ligne, la propriété vertical-align
Est responsable de l'alignement des éléments individuels.
Le point de référence le plus important à aligner verticalement est la ligne de base des éléments impliqués. Dans certains cas, les bords supérieur et inférieur de la boîte englobante de l'élément deviennent également importants.
Le bord supérieur et inférieur de la hauteur de ligne est indiqué par des lignes rouges, la hauteur de la police par des lignes vertes et la ligne de base par une ligne bleue.
À gauche , le texte a une hauteur de ligne définie à la même hauteur que la taille de police. La ligne verte et rouge s'est effondrée en une ligne de chaque côté.
Au milieu , la hauteur de la ligne est deux fois plus grande que la taille de la police.
À droite , la hauteur de la ligne est la moitié de la taille de la police.
Notez que les bords extérieurs de l'élément en ligne (les lignes rouges) n'ont pas d'importance, si la hauteur de la ligne est inférieure à la hauteur de la police.
De gauche à droite vous voyez:
un élément inline-block
avec in-flow content
un élément inline-block
avec in-flow contenu et overflow: hidden
un élément inline-block
sans in-flow contenu (mais la zone de contenu a une hauteur)
Les limites de la marge sont indiquées par des lignes rouges, la bordure est jaune, le remplissage vert et la zone de contenu bleu. La ligne de base de chaque élément inline-block
Est représentée par une ligne bleue.
La ligne de base de l'élément inline-block
Dépend du contenu de l'élément in-flow . En cas de:
in-flow content la ligne de base de l'élément inline-block
est la ligne de base du dernier élément de contenu dans le flux normal ( exemple à gauche)
in-flow content mais une propriété overflow
évaluant autre chose que visible, la ligne de base est le bord inférieur de la zone de marge ( exemple au milieu)
no in-flow content la ligne de base est, encore une fois, le bord inférieur de la zone de marge ( exemple à droite)
C'est probablement la partie la plus déroutante lorsque vous travaillez avec vertical-align
. Cela signifie que la ligne de base est placée là où elle doit être pour remplir toutes les autres conditions telles que vertical-align
Et en minimisant la hauteur de la zone de ligne. C'est un paramètre libre dans l'équation.
Étant donné que la ligne de base de la zone de ligne est invisible, il n'est pas toujours évident de savoir où elle se trouve. Mais, vous pouvez le rendre visible très facilement. Ajoutez simplement un caractère au début de la ligne dans les questions, comme le "x" sur la figure. Si ce personnage n'est aligné d'aucune façon, il se trouvera par défaut sur la ligne de base.
Autour de sa ligne de base, la zone de ligne a ce que l'on pourrait appeler sa zone de texte (lignes vertes sur la figure). La zone de texte peut simplement être considérée comme un élément en ligne à l'intérieur de la zone de ligne sans aucun alignement. Sa hauteur est égale au font-size
De son élément parent. Par conséquent, la zone de texte entoure uniquement le texte non formaté de la zone de ligne. Comme cette zone de texte est liée à la ligne de base, elle se déplace lorsque la ligne de base se déplace.
Si vous voulez faire des essais avec divers vertical-align
Et font-size
Ici, vous avez un extrait où vous pouvez l'essayer. Est également disponible en JSFiddle .
let sl1 = document.getElementById('sl1');
let sl2 = document.getElementById('sl2');
let sl3 = document.getElementById('sl3');
let sl4 = document.getElementById('sl4');
let Elm1 = document.getElementById('Elm1');
let Elm2 = document.getElementById('Elm2');
let Elm3 = document.getElementById('Elm3');
let Elm4 = document.getElementById('Elm4');
let ip1 = document.getElementById('ip1');
let ip2 = document.getElementById('ip2');
let ip3 = document.getElementById('ip3');
let ip4 = document.getElementById('ip4');
let slArr = [sl1, sl2, sl3, sl4];
let elmArr = [Elm1, Elm2, Elm3, Elm4];
let ipArr = [ip1, ip2, ip3, ip4];
let valueArr = ['baseline', 'top', 'middle', 'bottom'];
for (let i = 0; i < slArr.length; i++) {
slArr[i].addEventListener('change', (event) => {
elmArr[i].style.verticalAlign = event.target.value;
elmArr[i].innerHTML = event.target.value;
addDiv();
})
}
for (let i = 0; i < ipArr.length; i++) {
ipArr[i].addEventListener('change', (event) => {
elmArr[i].style.fontSize = event.target.value + 'em';
addDiv();
})
}
document.getElementById('btnRandom').addEventListener('click', () => {
for (let i = 0; i < elmArr.length; i++) {
let element = elmArr[i];
let fontSize = Math.floor(Math.random() * 4 + 1);
ipArr[i].value = fontSize;
element.style.fontSize = fontSize + 'em';
let styleIndex = Math.floor(Math.random() * 4);
element.style.verticalAlign = valueArr[styleIndex];
element.innerHTML = valueArr[styleIndex];
slArr[i].selectedIndex = styleIndex;
}
}, this);
function addDiv() {
let view = document.getElementById('viewer');
view.innerHTML = "";
elmArr.forEach(function(element) {
let div = document.createElement('div');
div.appendChild(element.cloneNode());
view.appendChild(div);
}, this);
}
.header span {
color: #000;
}
select {
width: 100px;
}
#elms {
border: solid 1px #000;
margin-top: 20px;
position: relative;
}
span {
color: #FFF;
font-size: 1em;
}
#Elm1 {
background-color: #300;
}
#Elm2 {
background-color: #6B0;
}
#Elm3 {
background-color: #90A;
}
#Elm4 {
background-color: #B00;
}
div {
z-index: -1;
}
#div1 {
width: 100%;
height: 1px;
background-color: #000;
position: absolute;
left: 0;
top: 25%;
}
#div2 {
width: 100%;
height: 1px;
background-color: #000;
position: absolute;
left: 0;
top: 50%;
}
#div3 {
width: 100%;
height: 1px;
background-color: #000;
position: absolute;
left: 0;
top: 75%;
}
<div class="header"> <span style="width: 100px;display: block;float: left;margin-right: 20px;">vertical align</span> <span>font-size(em)</span> </div>
<div>
<select name="sl1" id="sl1">
<option value="baseline">baseline</option>
<option value="top">top</option>
<option value="middle">middle</option>
<option value="bottom">bottom</option>
</select>
<input type="number" value="1" id="ip1" />
<br>
<select name="sl2" id="sl2">
<option value="baseline">baseline</option>
<option value="top">top</option>
<option value="middle">middle</option>
<option value="bottom">bottom</option>
</select>
<input type="number" value="1" id="ip2" />
<br>
<select name="sl3" id="sl3">
<option value="baseline">baseline</option>
<option value="top">top</option>
<option value="middle">middle</option>
<option value="bottom">bottom</option>
</select>
<input type="number" value="1" id="ip3" />
<br>
<select name="sl4" id="sl4">
<option value="baseline">baseline</option>
<option value="top">top</option>
<option value="middle">middle</option>
<option value="bottom">bottom</option>
</select>
<input type="number" value="1" id="ip4" />
<br>
<button id="btnRandom" (onclick)="random()">Random</button>
</div>
<div id="elms">
<span id="Elm1">one</span>
<span id="Elm2">two</span>
<span id="Elm3">three</span>
<span id="Elm4">four</span>
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
</div>
<div id="viewer"></div>
Cet extrait est créé par Duannx .
Source: Veuillez noter qu'il s'agit d'un extrait de Vertical-Align: All You Need To Know écrit par Christopher Aue.
La question est de savoir pourquoi vertical-align: baseline;
ignoré. Eh bien, je ne pense pas. Dans votre premier extrait, vous utilisez baseline
et bottom
ce qui donne clairement une différence entre les deux <span>
éléments. Alors, que fait baseline
? Eh bien baseline
Aligne la ligne de base de l'élément avec la ligne de base de l'élément parent. Dans l'exemple ci-dessous, j'ai copié et ajusté certaines parties pour donner la différence.
span.one {vertical-align:baseline}
span.two {vertical-align:middle;}
<p>
<span class="one">one</span> <span class="two">two</span>
</p>
Comme vous pouvez le voir, l'alignement baseline
agit normalement tout comme l'alignement middle
.
Permet maintenant de tester autre chose. permet d'échanger l'alignement de baseline
et middle
et d'éditer middle
et d'ajouter un troisième <span>
span.one { vertical-align: top;}
span.two { vertical-align: baseline;}
span.three {vertical-align: middle; height: 20px; }
p {
height: 50px;
background-color: grey;
}
<p>
<span class="one">one</span> <span class="two">two</span> <span class="two">two</span><br><br> <span class="three">three</span>
</p>
Maintenant, si vous éditez le deuxième extrait et jetez un œil au vertical-align
de <span class="three">
vous pouvez voir clairement qu'en changeant l'alignement le texte change sa position.
Mais votre question concerne le texte sur la même ligne, jetons un coup d'œil à l'extrait ci-dessous.
span.one { vertical-align: middle;}
span.two { vertical-align: baseline;}
span.three {vertical-align: middle; height: 20px; }
p {
height: 50px;
background-color: grey;
}
<p>
<span class="one">one</span> <span class="two">two</span> <span class="two">two</span><span class="three">three</span>
</p>
Comme vous pouvez le voir dans ce troisième extrait, j'ai placé le troisième <span>
à côté d'un et deux. Et cela fait une différence. Le baseline
dans ce cas est différent de l'alignement middle
. En effet, le baseline
saisit le baseline
du parent. comme la hauteur du parent est normale, cela n'affecte pas l'alignement de baseline
et top
. mais quand vous utiliserez middle
ou sub
c'est clairement une différence.
Pour plus d'informations sur chaque alignement, consultez ceci lien .