Comment aligner les cases à cocher et leurs étiquettes de manière cohérente entre les navigateurs

1735

C'est l'un des problèmes CSS mineurs qui me tourmente constamment. Comment les gens autour de Stack Overflow s'alignent verticalement checkboxeset leur cross-browserlabels cohérent ? Chaque fois que je les aligne correctement dans Safari (généralement sur le ), ils sont complètement désactivés dans Firefox et IE. Corrigez-le dans Firefox, et Safari et IE sont inévitablement foirés. Je perds du temps à chaque fois que je code un formulaire.vertical-align: baselineinput

Voici le code standard avec lequel je travaille:

<form>
    <div>
        <label><input type="checkbox" /> Label text</label>
    </div>
</form>

J'utilise généralement la réinitialisation d'Eric Meyer, donc les éléments de formulaire sont relativement exempts de remplacements. Dans l'attente de tous les conseils ou astuces que vous avez à offrir!

One Crayon
la source
7
Placez chaque case à cocher et étiquette dans un élément <li>. Ajouter un débordement: caché à <li> et faire flotter l'étiquette et la case à gauche. Ensuite, ils s'alignent tous parfaitement bien. Ne mettez pas la case à cocher dans l'élément d'étiquette de toute évidence.
volume un
5
Je l'ai atteint en utilisant les attributs heightet line-height, jetez un œil à jsfiddle.net/wepw5o57/3
TheGr8_Nik
Manipulation positionet toprésolution de ce problème Exemple: jsfiddle.net/ynkjc22s
Profesor08
2019. toujours le même problème. encore besoin de quelques hacks pour le faire fonctionner :(
dieter
@dieter voir ma réponse, j'ai expliqué pourquoi les hacks sont nécessaires et quelle approche n'est pas hacky: stackoverflow.com/a/56558431/3995261
YakovL

Réponses:

1010

Après plus d'une heure de peaufinage, de test et d'essais de différents styles de balisage, je pense avoir une solution décente. Les exigences pour ce projet particulier étaient:

  1. Les entrées doivent être sur leur propre ligne.
  2. Les entrées de case à cocher doivent s'aligner verticalement avec le texte de l'étiquette de manière similaire (sinon identique) dans tous les navigateurs.
  3. Si le texte de l'étiquette se termine, il doit être mis en retrait (donc pas de retour sous la case à cocher).

Avant d'entrer dans une explication, je vais juste vous donner le code:

label {
  display: block;
  padding-left: 15px;
  text-indent: -15px;
}
input {
  width: 13px;
  height: 13px;
  padding: 0;
  margin:0;
  vertical-align: bottom;
  position: relative;
  top: -1px;
  *overflow: hidden;
}
<form>
  <div>
    <label><input type="checkbox" /> Label text</label>
  </div>
</form>

Voici l'exemple de travail dans JSFiddle .

Ce code suppose que vous utilisez une réinitialisation comme Eric Meyer qui ne remplace pas les marges et le remplissage d'entrée de formulaire (d'où la réinitialisation de la marge et du remplissage dans le CSS d'entrée). De toute évidence, dans un environnement en direct, vous allez probablement imbriquer / remplacer des éléments pour prendre en charge d'autres éléments d'entrée, mais je voulais que les choses soient simples.

A noter:

  • La *overflowdéclaration est un hack IE en ligne (le hack star-property). IE 6 et 7 le remarqueront, mais Safari et Firefox l'ignoreront correctement. Je pense que ce pourrait être un CSS valide, mais vous êtes toujours mieux avec des commentaires conditionnels; je l'ai utilisé pour plus de simplicité.
  • Du mieux que je puisse dire, la seule vertical-aligndéclaration qui était cohérente entre les navigateurs était vertical-align: bottom. La définition de ce paramètre et le positionnement relatif vers le haut se sont comportés de manière presque identique dans Safari, Firefox et IE avec seulement un ou deux pixels de différence.
  • Le problème majeur du travail avec l'alignement est qu'IE colle un tas d'espace mystérieux autour des éléments d'entrée. Ce n'est pas du rembourrage ou de la marge, et c'est sacrément persistant. Définir une largeur et une hauteur sur la case à cocher, puis overflow: hiddenpour une raison quelconque, coupe l'espace supplémentaire et permet au positionnement d'IE d'agir de manière très similaire à Safari et Firefox.
  • En fonction de la taille de votre texte, vous aurez sans doute besoin d'ajuster le positionnement relatif, la largeur, la hauteur, etc. pour que les choses soient correctes.

J'espère que ceci aide quelqu'un d'autre! Je n'ai essayé cette technique spécifique sur aucun autre projet que celui sur lequel je travaillais ce matin, alors n'hésitez pas à trouver quelque chose qui fonctionne de manière plus cohérente.

One Crayon
la source
8
Remarque. Vous devriez probablement mettre un attribut "pour" sur votre étiquette, pour vous assurer qu'il fonctionne pour tous les navigateurs et lecteurs de texte. (Je me rends compte que vous l'avez probablement laissé pour la simplicité)
Armstrongest
306
Bon sang, je n'avais pas réalisé combien de personnes l'ignoraient: si vous encapsulez l'entrée dans la balise label, l'attribut "for" n'est pas nécessaire. N'hésitez pas à voir par vous-même: w3.org/TR/html401/interact/forms.html#h-17.9.1
One Crayon
10
Je ne suis pas d'accord avec la suggestion d'utiliser des commentaires conditionnels. Gardez le hack CSS * foobar. Cela fonctionne bien, est utilisé par des frameworks comme YUI, et vous permet de garder ensemble ce qui appartient ensemble.
ebruchez
50
Je l'ai
9
Remarque, cela ne semble pas fonctionner dans les dernières versions de Chrome (j'utilise la v36). i.imgur.com/y9Ffxsh.png Edit: ni Firefox (v31)
Hans
214

Parfois, l'alignement vertical nécessite deux éléments en ligne (span, label, input, etc ...) côte à côte pour fonctionner correctement. Les cases à cocher suivantes sont correctement centrées verticalement dans IE, Safari, FF et Chrome, même si la taille du texte est très petite ou grande.

Ils flottent tous côte à côte sur la même ligne, mais le nowrap signifie que le texte entier de l'étiquette reste toujours à côté de la case à cocher.

L'inconvénient est les balises SPAN supplémentaires sans signification.

.checkboxes label {
  display: inline-block;
  padding-right: 10px;
  white-space: nowrap;
}
.checkboxes input {
  vertical-align: middle;
}
.checkboxes label span {
  vertical-align: middle;
}
<form>
  <div class="checkboxes">
    <label for="x"><input type="checkbox" id="x" /> <span>Label text x</span></label>
    <label for="y"><input type="checkbox" id="y" /> <span>Label text y</span></label>
    <label for="z"><input type="checkbox" id="z" /> <span>Label text z</span></label>
  </div>
</form>

Maintenant, si vous aviez un texte d'étiquette très long qui devait être enveloppé sans être placé sous la case à cocher, vous utiliseriez un remplissage et un retrait de texte négatif sur les éléments d'étiquette:

.checkboxes label {
  display: block;
  padding-right: 10px;
  padding-left: 22px;
  text-indent: -22px;
}
.checkboxes input {
  vertical-align: middle;
}
.checkboxes label span {
  vertical-align: middle;
}
<form>
  <div class="checkboxes">
    <label for="x"><input type="checkbox" id="x" /> <span>Label text x so long that it will probably wrap so let's see how it goes with the proposed CSS (expected: two lines are aligned nicely)</span></label>
    <label for="y"><input type="checkbox" id="y" /> <span>Label text y</span></label>
    <label for="z"><input type="checkbox" id="z" /> <span>Label text z</span></label>
  </div>
</form>

Nathan Bowers
la source
19
Merci! Le "vertical-align: middle" à la fois sur l'entrée et la plage a très bien fonctionné pour moi.
William Gross
6
display: block; float: left;semble être redondant
PHPst
4
Vous n'avez pas besoin d'utiliser un attribut for lorsque vous avez l'entrée à l'intérieur de l'étiquette. Ça marche sans ça.
Tommy Sørensen
6
Cela devrait être la réponse acceptée par mon opinion. Aucun ajustement n'est nécessaire.
Tim
4
Impressionnant et confirmé fonctionne toujours sur Chrome 58 (Windows) (contrairement à la première réponse actuelle).
Jason C
188

En travaillant avec la solution de One Crayon , j'ai quelque chose qui fonctionne pour moi et qui est plus simple:

.font2 {font-family:Arial; font-size:32px} /* Sample font */

input[type=checkbox], input[type=radio] {
  vertical-align: middle;
  position: relative;
  bottom: 1px;
}

input[type=radio] { 
  bottom: 2px; 
} 
<label><input type="checkbox" /> Label text</label>
<p class="font2">
  <label><input type="checkbox"/> Label text</label>
</p>

Rend pixel par pixel la même chose dans Safari (dont je fais confiance à la ligne de base) et Firefox et IE7 sont tous les deux aussi bons. Il fonctionne également pour différentes tailles de police d'étiquette, grandes et petites. Maintenant, pour fixer la ligne de base d'IE sur les sélections et les entrées ...


Mise à jour: (modification tierce)

La bottomposition correcte dépend de la famille de polices et de la taille de police! J'ai trouvé que l'utilisation bottom: .08em;de la case à cocher et des éléments radio est une bonne valeur générale. Je l'ai testé dans Chrome / Firefox / IE11 sous Windows avec les polices Arial et Calibri en utilisant plusieurs tailles de police petites / moyennes / grandes.

.font2, .font2 input {font-family:Arial; font-size:32px} /* Sample font */

input[type=checkbox], input[type=radio] {
  vertical-align: middle; 
  position: relative;
  bottom: .08em; /* this is a better value for different fonts! */
}
<label><input type="checkbox" /> Label text</label> 

<p class="font2">
  <label><input type="checkbox"/> Label text</label>
</p>

S.Serpooshan
la source
10
Juste une remarque pour les autres: cela ne fonctionnera pas dans IE6 car il ne prend pas en charge le ciblage CSS [type = checkbox].
One Crayon
3
Vous pouvez simplement ajouter une classe au lieu d'utiliser des sélecteurs non pris en charge si la prise en charge d'IE6 est requise.
HartleySan
1
Celui-ci a fonctionné pour moi. Cependant, au lieu de définir "position: relative; bottom: 1px", vous pouvez utiliser "margin: 0 0 1px 0" pour obtenir le même résultat.
newman
142

Une chose simple qui semble bien fonctionner est d'appliquer un réglage de la position verticale de la case à cocher avec alignement vertical. Il variera toujours d'un navigateur à l'autre, mais la solution n'est pas compliquée.

input {
    vertical-align: -2px;
}

Référence

Frank Schwieterman
la source
9
C'était le plus petit changement parmi tous les autres, ce qui fonctionne pour moi dans les versions les plus récentes des navigateurs.
Johnny_D
6
Cela fonctionne encore mieux qu'avec vertical-alignet position: relativeparce qu'il fonctionne également correctement dans IE9 :)
Dennis98
5
mais cela dépend de la taille de la police. pour les grandes tailles de police, il doit être ajusté à des valeurs négatives plus élevées, par exemple: vertical-align: -6px;
S.Serpooshan
1
cela peut probablement fonctionner mieux avec différentes polices si elles sont définiesem
YakovL
92

essayer vertical-align: middle

aussi votre code semble qu'il devrait être:

<form>
    <div>
        <input id="blah" type="checkbox"><label for="blah">Label text</label>
    </div>
</form>

digitalsanctum
la source
<label for="blah">n'est nécessaire que si vous utilisez quelque chose où il n'est pas logique que l'étiquette soit enveloppée (comme une zone de texte; je l'utilise généralement <label for="blah">Foo</label><input id="blah" type="text" />dans ce cas). Avec les cases à cocher, je trouve que c'est moins de balisage pour l'envelopper.
One Crayon
13
Pas exactement vrai: le Label-for permettra aux utilisateurs de cliquer sur l'étiquette afin de cocher la case, en plus de simplement cliquer sur la case à cocher elle-même. C'est assez pratique pour lier les deux éléments ensemble.
EndangeredMassa
26
Si une entrée est imbriquée dans une étiquette, cliquer sur l'étiquette avec activer / donner le focus à l'entrée; l'attribut for est uniquement pour le cas où l'entrée n'est pas imbriquée.
One Crayon
3
C'est vrai crayon, mais il est toujours une bonne pratique d'utiliser le « pour » attribut, ou vous aurez des problèmes avec certains navigateurs qui ne reconnaissent pas cette syntaxe toux IE.
Armstrongest
si vous ne voulez pas que votre case à cocher ait un identifiant, vous devez envelopper la case à l'intérieur de l'étiquette
Simon_Weaver
39

Essayez ma solution, je l'ai essayée dans IE 6, FF2 et Chrome et elle rend pixel par pixel dans les trois navigateurs.

* {
  padding: 0px;
  margin: 0px;
}
#wb {
  width: 15px;
  height: 15px;
  float: left;
}
#somelabel {
  float: left;
  padding-left: 3px;
}
<div>
  <input id="wb" type="checkbox" />
  <label for="wb" id="somelabel">Web Browser</label>
</div>

Waleed Eissa
la source
3
Intéressant; J'aime l'idée de faire flotter les deux éléments; qui résout élégamment le problème de wrapping. Je suis attaché à emballer les entrées avec une étiquette, mais ce code est beaucoup plus propre que la solution à laquelle je suis arrivé.
One Crayon
dans cet exemple, la case à cocher entrée et l'étiquette doivent également avoir une propriété display: block et dans ce cas, ils seront traités comme des DIV normaux qui peuvent être alignés facilement
se_pavel
5
cela a un problème, que se passe-t-il si l'étiquette ne rentre pas dans l'espace disponible? l'étiquette et la case à cocher sont séparées (la case à cocher est en haut à droite et l'étiquette en bas à gauche). Si vous cochez la case à l'intérieur de votre étiquette, vous n'avez pas ce problème.
Enrique
Cela ne fonctionnait pas au pixel près, mais c'était suffisamment décent pour que les choses soient plus belles sur les 3 principaux navigateurs. Je suppose que j'aurais pu passer une heure de plus pour voir que ça marcherait mieux ...
Alexis Wilke
26

La seule solution qui fonctionne parfaitement pour moi est:

input[type=checkbox], input[type=radio] {
    vertical-align: -2px;
    margin: 0;
    padding: 0;
}

Testé aujourd'hui dans Chrome, Firefox, Opera, IE 7 et 8. Exemple: Fiddle

Buzogany Laszlo
la source
22

Je n'ai pas complètement testé ma solution, mais elle semble très bien fonctionner.

Mon HTML est simplement:

<label class="checkbox"><input type="checkbox" value="0000">0000 - 0100</label>

J'ai ensuite défini toutes les cases à cocher 24pxpour la hauteur et la largeur. Pour rendre le texte aligné je fais l'étiquette est line-heightaussi 24pxet assign vertical-align: top;comme ceci:

EDIT: Après les tests IE, j'ai ajouté vertical-align: bottom;à l'entrée et changé le CSS du label. Vous pouvez trouver que vous avez besoin d'un cas css IE conditionnel pour trier le remplissage - mais le texte et la boîte sont en ligne.

input[type="checkbox"] {
    width: 24px;
    height: 24px;
    vertical-align: bottom;
}
label.checkbox {
    vertical-align: top;
    line-height: 24px;
    margin: 2px 0;
    display: block;
    height: 24px;
}
<label class="checkbox"><input type="checkbox" value="0000">0000 - 0100</label>
<label class="checkbox"><input type="checkbox" value="0100">0100 - 0200</label>
<label class="checkbox"><input type="checkbox" value="0200">0200 - 0300</label>
<label class="checkbox"><input type="checkbox" value="0300">0300 - 0400</label>

Si quelqu'un constate que cela ne fonctionne pas, veuillez me le faire savoir. Le voici en action (dans Chrome et IE - excuses car des captures d'écran ont été prises sur la rétine et en utilisant des parallèles pour IE):

capture d'écran des cases à cocher: Chrome capture d'écran des cases à cocher: IE

Patrick
la source
1
C'est assez ancien, mais puisque vous avez demandé à vous le faire savoir, cela ne fonctionne pas bien dans FireFox (les cases à cocher sont au-dessus de la ligne de base). Vous pouvez être intéressé par une explication détaillée que j'ai publiée
YakovL
20

J'utilise généralement la hauteur de ligne afin d'ajuster la position verticale de mon texte statique:

label {
  line-height: 18px;
}
input {
  width: 13px;
  height: 18px;
  font-size: 12px;
  line-height: 12px;
}
<form>
  <div>
    <label><input type="checkbox" /> Label text</label>
  </div>
</form>

J'espère que cela pourra aider.

Plan B
la source
hauteur de ligne, duh. Oubliez toujours celui-là. Bon travail, fonctionne très bien.
Craig
13

<form>
    <div>
        <label style="display: inline-block">
            <input style="vertical-align: middle" type="checkbox" />
            <span style="vertical-align: middle">Label text</span>
         </label>
    </div>
</form>

L'astuce consiste à utiliser l'alignement vertical uniquement dans les cellules du tableau ou le bloc en ligne si vous utilisez une étiquette d'étiquette.

Carlo Pires
la source
11

Jetons enfin un œil à la source du problème

Les cases à cocher sont rendues à l'aide d'images (on peut en définir des personnalisées via CSS). Voici une case à cocher (non cochée) dans FireFox, mise en évidence avec l'inspecteur DOM:

c'est juste un carré

Et voici la même case à cocher sans style dans Chrome:

c'est un carré non centré avec des "marges" à droite et en bas

Vous pouvez voir la marge (orange); le rembourrage n'est pas présent (serait affiché en vert). Alors, quelle est cette pseudo-marge à droite et en bas de la case à cocher? Ce sont des parties de l'image utilisées pour la case à cocher . C'est pourquoi l'utilisation vertical-align: middlene suffit pas vraiment et c'est la source des problèmes entre les navigateurs.

Alors, que pouvons-nous faire à ce sujet?

Une option évidente est - remplacez les images! Heureusement, on peut le faire via CSS et remplacer ceux-ci par des images externes, des images base64 (en CSS), des svg en CSS ou simplement des pseudo-éléments. C'est une approche robuste (multi-navigateur!), Et voici un exemple d'un tel ajustement dérobé à cette question :

.checkbox-custom {
  opacity: 0;
  position: absolute;
}
.checkbox-custom,
.checkbox-custom-label {
  display: inline-block;
  vertical-align: middle;
  margin: 5px;
  cursor: pointer;
}
.checkbox-custom + .checkbox-custom-label:before {
  content: '';
  display: inline-block;
  background: #fff;
  border-radius: 5px;
  border: 2px solid #ddd;
  vertical-align: middle;
  width: 10px;
  height: 10px;
  padding: 2px;
  margin-right: 10px;
  text-align: center;
}
.checkbox-custom:checked + .checkbox-custom-label:before {
  width: 1px;
  height: 5px;
  border: solid blue;
  border-width: 0 3px 3px 0;
  transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  border-radius: 0px;
  margin: 0px 15px 5px 5px;
}
<div>
  <input id="checkbox-1" class="checkbox-custom" name="checkbox-1" type="checkbox">
  <label for="checkbox-1" class="checkbox-custom-label">First Choice</label>
</div>
<div>
  <input id="checkbox-2" class="checkbox-custom" name="checkbox-2" type="checkbox">
  <label for="checkbox-2" class="checkbox-custom-label">Second Choice</label>
</div>

Vous voudrez peut-être lire quelques articles plus approfondis sur un tel style comme certains répertoriés ici ; c'est hors de portée de cette réponse.

Ok, qu'en est-il encore de la solution sans images personnalisées ou pseudo-éléments?

TL; DR: cela ne fonctionnera pas, utilisez plutôt une case à cocher personnalisée

Tout d'abord, notons que si dans d'autres navigateurs ces pseudo-marges à l'intérieur de l'icône de case à cocher étaient arbitraires, il n'y avait pas de solution cohérente. Pour en construire une, nous devons explorer l'anatomie de ces images dans les navigateurs existants.

Alors, quels navigateurs ont les pseudo-marges dans les cases à cocher? J'ai vérifié Chrome 75, Vivaldi 2.5 (à base de chrome), FireFox 54 (ne demandez pas pourquoi un tel obsolète), IE 11, Edge 42, Safari ?? (emprunté un pour une minute, j'ai oublié de vérifier la version). Seuls Chrome et Vivaldi ont de telles pseudo-marges (je soupçonne également tous les navigateurs basés sur Chromium, comme Opera).

Quelle est la taille de ces pseudo-marges? Pour comprendre cela, on peut utiliser une case à cocher zoomée:

input {
  zoom: 10;
  box-shadow: 0 0 1px inset #999;
}
<input type=checkbox>

mon résultat est ~ 7% de largeur / hauteur et donc 0,9-1,0 px en unités absolues. La précision peut cependant être mise en doute: essayez différentes valeurs de zoompour la case à cocher. Dans mes tests dans Chrome et Vivaldi, la taille relative de la pseudo-marge est très différente aux zoomvaleurs 10, 20 et aux valeurs 11-19 (??):

pour zoom = 10 c'est 7% tandis que pour le zoom = 11, c'est presque le double de cette valeur

scale semble être plus cohérent:

input {
  transform: scale(10) translate(50%, 50%);
  box-shadow: 0 0 1px inset #999;
}
<input type=checkbox>

donc probablement ~ 14% et 2px sont les valeurs correctes.

Maintenant que nous connaissons (?) La taille de la pseudo-marge, notons que cela ne suffit pas. Les tailles des icônes des cases à cocher sont-elles les mêmes pour tous les navigateurs? Hélas! Voici ce que l'inspecteur DOM affiche pour les cases à cocher sans style:

  • FireFox: 13,3 px
  • À base de chrome: 12,8 pixels pour l'ensemble, donc 12,8 (100% - 14%) = 11 pixels pour ce qui est visuellement perçu comme une case à cocher
  • IE 11, Edge: 13px
  • Safari: n / a (ceux-ci devraient être comparés sur le même écran, je crois)

Avant de discuter de solutions ou d'astuces, demandons: qu'est-ce qu'un alignement correct ? Que voulons-nous atteindre? À un certain point, c'est une question de goût, mais en gros, je peux penser aux aspects "sympas" des alignements suivants:

texte et case à cocher sur la même ligne de base (je ne modifie délibérément pas la taille de la case à cocher ici):

entrez la description de l'image ici

ou avoir la même ligne médiane en termes de lettres minuscules:

entrez la description de l'image ici

ou même ligne médiane en termes de lettres majuscules (il est plus facile de voir la différence pour différentes tailles de police):

entrez la description de l'image ici

et nous devons également décider si la taille de la case à cocher doit être égale à la hauteur d'une lettre minuscule, d'une lettre majuscule ou autre (plus grande, plus petite ou entre minuscules et majuscules).

Pour cette discussion, appelons un alignement agréable si la case à cocher est sur la même ligne de base que le texte et a la taille d'une lettre majuscule (un choix très discutable):

entrez la description de l'image ici

Maintenant, quels outils devons-nous:

  1. ajuster la taille de la case à cocher
  2. reconnaître Chromium avec sa case à cocher pseudo-margée et définir des styles spécifiques
  3. ajuster l'alignement vertical de la case à cocher / de l'étiquette

?

  1. En ce qui concerne l' ajustement de la taille des cases à cocher : il y a width, height, size, zoom, scale(ai - je raté quelque chose?). zoomet scalene permettent pas de définir la taille absolue, ils peuvent donc aider uniquement à ajuster la taille du texte, pas définir la taille multi-navigateur (sauf si nous pouvons écrire des règles spécifiques au navigateur). sizene fonctionne pas avec Chrome (est-ce que cela fonctionnait avec l'ancien IE? de toute façon, ce n'est pas si intéressant). widthet heightfonctionne dans Chrome et d'autres navigateurs, afin que nous puissions définir une taille commune, mais encore une fois, dans Chrome, il définit la taille de l'image entière, pas la case à cocher elle-même. Remarque: c'est le minimum (largeur, hauteur) qui définit la taille d'une case à cocher (si largeur ≠ hauteur, la zone en dehors du carré de case à cocher est ajoutée à la "pseudo-marge").

    Une chose regrettable est que les pseudo-marges dans la case à cocher Chrome ne sont pas définies sur zéro pour toute largeur et hauteur, pour autant que je puisse voir.

  2. Je crains qu'il n'y ait pas de méthode fiable uniquement en CSS de nos jours.

  3. Considérons l'alignement vertical. vertical-alignne peut pas donner de résultats cohérents lorsqu'il est défini sur middleou à baselinecause de la pseudo-marge de Chrome, la seule véritable option pour obtenir le même "système de coordonnées" pour tous les navigateurs est d'aligner l'étiquette et l'entrée sur top:

    comparaison d'alignement vertical: haut et bas

    (sur l'image: alignement vertical: haut, bas et bas sans boîte-ombre)

Alors, quel résultat en tirons-nous?

input[type="checkbox"] {
    height: 0.95em;
    width: 0.95em;
}
label, input {
    vertical-align: top;
}
<label><input type="checkbox">label</label>

L'extrait ci-dessus fonctionne avec Chrome (navigateurs à base de chrome), mais les autres navigateurs nécessitent une taille de case à cocher plus petite. Il semble impossible d'ajuster à la fois la taille et l'alignement vertical de manière à contourner la bizarrerie de l'image de la case à cocher de Chromium. Ma dernière suggestion est: utilisez plutôt des cases à cocher personnalisées - et vous éviterez la frustration :)

YakovL
la source
Cette réponse est si profonde!
Marecky
10

Maintenant que flexbox est pris en charge dans tous les navigateurs modernes, quelque chose comme ça semble être une approche plus facile pour moi.

<style>
label {
  display: flex;
  align-items: center;
}
input[type=radio], input[type=checkbox]{
  flex: none;
}
</style>
<form>
  <div>
    <label><input type="checkbox" /> Label text</label>
  </div>
</form>


Voici la démo complète de la version préfixée:

Bryan Willis
la source
10

Je pense que c'est le moyen le plus simple

input {
    position: relative;
    top: 1px;
}
<form>
    <div>
        <label><input type="checkbox" /> Label text</label>
    </div>
<form>

gidzior
la source
la question est: cela fonctionne-t-il bien dans tous les navigateurs? ;-)
JonSnow
9

Je n'aime pas le positionnement relatif, car il rend l'élément rendu au-dessus de tout le reste à son niveau (il peut aller au-dessus de quelque chose si vous avez une disposition complexe).

J'ai découvert que les vertical-align: subcases à cocher sont suffisamment alignées dans Chrome, Firefox et Opera. Impossible de vérifier Safari car je n'ai pas MacOS et IE10 est légèrement éteint, mais j'ai trouvé que c'était une assez bonne solution pour moi.

Une autre solution pourrait être d'essayer de créer des CSS spécifiques pour chaque navigateur et de les affiner avec un alignement vertical en% / pixels / EM: http://css-tricks.com/snippets/css/browser-specific-hacks/

waterplea
la source
Semble fonctionner tant que la taille de la police n'est pas trop grande.
robsch
9

Cela fonctionne bien pour moi:

fieldset {
  text-align:left;
  border:none
}
fieldset ol, fieldset ul {
  padding:0;
  list-style:none
}
fieldset li {
  padding-bottom:1.5em;
  float:none;
  clear:left
}
label {
  float:left;
  width:7em;
  margin-right:1em
}
fieldset.checkboxes li {
  clear:both;
  padding:.75em
}
fieldset.checkboxes label {
  margin:0 0 0 1em;
  width:20em
}
fieldset.checkboxes input {
  float:left
}
<form>
  <fieldset class="checkboxes">
    <ul>
      <li>
        <input type="checkbox" name="happy" value="yep" id="happy" />
        <label for="happy">Happy?</label>
      </li>
      <li>
        <input type="checkbox" name="hungry" value="yep" id="hungry" />
        <label for="hungry">Hungry?</label>
      </li>
    </ul>
  </fieldset>
</form>

dylanfm
la source
8
vous bénisse pour utiliser ems au lieu de pxs.
IDisposable
7

La réponse choisie avec plus de 400 votes positifs n'a pas fonctionné pour moi dans Chrome 28 OSX, probablement parce qu'elle n'a pas été testée dans OSX ou qu'elle a fonctionné dans tout ce qui existait en 2008 lorsque cette question a été répondue.

Les temps ont changé et de nouvelles solutions CSS3 sont désormais possibles. Ma solution utilise des pseudo-éléments pour créer une case à cocher personnalisée . Ainsi, les stipulations (pour ou contre, quelle que soit la façon dont vous les regardez) sont les suivantes:

  • Fonctionne uniquement dans les navigateurs modernes (FF3.6 +, IE9 +, Chrome, Safari)
  • S'appuie sur une case à cocher conçue sur mesure, qui sera rendue exactement la même dans chaque navigateur / OS. Ici, je viens de choisir des couleurs simples, mais vous pouvez toujours ajouter des dégradés linéaires et autres pour lui donner plus d'impact.
  • Est adapté à une certaine police / taille de police, qui si elle était modifiée, vous changeriez simplement le positionnement et la taille de la case à cocher pour la faire apparaître verticalement alignée. S'il est modifié correctement, le résultat final devrait toujours être presque identique dans tous les navigateurs / systèmes d'exploitation.
  • Pas de propriétés d'alignement vertical, pas de flotteurs
  • Doit utiliser le balisage fourni dans mon exemple, cela ne fonctionnera pas s'il est structuré comme la question, cependant, la mise en page sera essentiellement la même. Si vous voulez déplacer des choses, vous devrez également déplacer le CSS associé

div.checkbox {
    position: relative;
    font-family: Arial;
    font-size: 13px;
}
label {
    position: relative;
    padding-left: 16px;
}
label::before {
    content :"";
    display: inline-block;
    width: 10px;
    height: 10px;
    background-color: white;
    border: solid 1px #9C9C9C;
    position: absolute;
    top: 1px;
    left: 0px;
}
label::after {
    content:"";
    width: 8px;
    height: 8px;
    background-color: #666666;
    position: absolute;
    left: 2px;
    top: 3px;
    display: none;
}
input[type=checkbox] {
    visibility: hidden;
    position: absolute;
}
input[type=checkbox]:checked + label::after {
    display: block;
}
input[type=checkbox]:active + label::before {
    background-color: #DDDDDD;
}
<form>
    <div class="checkbox">
        <input id="check_me" type=checkbox />
        <label for="check_me">Label for checkbox</label>
    </div>
</form>

Cette solution masque la case à cocher et ajoute et stylise des pseudo-éléments à l'étiquette pour créer la case à cocher visible. Étant donné que l'étiquette est liée à la case à cocher masquée, le champ de saisie sera toujours mis à jour et la valeur sera soumise avec le formulaire.

Et si vous êtes intéressé, voici mon point de vue sur les boutons radio: http://jsfiddle.net/DtKrV/2/

J'espère que quelqu'un trouve cela utile!

MusikAnimal
la source
6

Je n'ai jamais eu de problème avec ça:

<form>
  <div>
    <input type="checkbox" id="cb" /> <label for="cb">Label text</label>
  </div>
</form>
John Topley
la source
4
Comme je l'ai dit aux affiches précédentes qui ont recommandé: Je n'aime pas ça car cela nécessite un balisage inutile. J'ai également essayé ce balisage, mais il était difficile d'empêcher l'étiquette de passer sous l'entrée (tout en ayant chacun un groupe d'étiquettes / d'entrée sur leurs propres lignes).
One Crayon
7
Donc, au lieu d'un balisage "inutile" (utilisé par presque tout le monde), vous préférez un CSS inutile?
Robert C.Barth
10
Le problème avec les emballages est. Mais en général, oui, je préfère avoir du CSS superflu que du balisage car le CSS est mis en cache, mais le balisage peut devoir être chargé à nouveau pour chaque nouvelle page.
One Crayon
4
Comparer: 1 instance de CSS supplémentaire -vs- de nombreuses instances de balisage supplémentaire.
Greg
6

Si vous utilisez des formulaires Web ASP.NET, vous n'avez pas à vous soucier des DIV et d'autres éléments ou des tailles fixes. Nous pouvons aligner le <asp:CheckBoxList>texte en définissant float:leftle type d'entrée CheckboxList en CSS.

Veuillez vérifier l'exemple de code suivant:

.CheckboxList
{
    font-size: 14px;
    color: #333333;
}
.CheckboxList input
{
    float: left;
    clear: both;
}

Code .ASPX:

<asp:CheckBoxList runat="server" ID="c1" RepeatColumns="2" CssClass="CheckboxList">
</asp:CheckBoxList>
Rama Subba Reddy M
la source
3

Si vous utilisez Twitter Bootstrap, vous pouvez simplement utiliser la checkboxclasse sur <label>:

<label class="checkbox">
    <input type="checkbox"> Remember me
</label>
Sunil D.
la source
3

Avec une case à cocher de type d'entrée enveloppée à l'intérieur de l'étiquette et flottant vers la gauche comme suit:

<label for="id" class="checkbox">
    <input type="checkbox" id="id">
    <span>The Label</span>
</label>

cela a fonctionné pour moi:

label.checkbox {
    display: block;
}
.checkbox input {
    float: left;
    height: 18px;
    vertical-align: middle;
}
.checkbox span {
    float: left;
    line-height: 18px;
    margin: 0 0 0 20px;
}

Assurez-vous que la hauteur du est identique à la hauteur de ligne du (niveau de bloc).

Matijs
la source
3

Codez en dur la hauteur et la largeur de la case à cocher, supprimez son rembourrage et faites sa hauteur plus les marges verticales égales à la hauteur de ligne de l'étiquette. Si le texte de l'étiquette est en ligne, faites flotter la case. Firefox, Chrome et IE7 + rendent tous l'exemple suivant identique: http://www.kornea.com/css-checkbox-align

utilisateur2407309
la source
Agréable! Mais vous devriez envisager de copier le code HTML et CSS ici. Les réponses qui dépendent tellement d'un lien externe sont déconseillées. Le lien est toujours utile pour voir les résultats, mais je pense que montrer le code ici vous aidera à obtenir plus de votes.
Mariano Desanze
non, ils ne le font pas (comparer dans FireFox et dans Chrome, dans Chrome les cases à cocher sont au-dessus de la ligne de base), j'ai expliqué pourquoi
YakovL
Pourquoi, vous revendiquez la chose qui n'est pas prise en charge, même avec des captures d'écran des deux navigateurs. C'est votre travail de fournir des preuves d'une réclamation lorsque vous en faites une, et non celle des autres pour la réfuter. J'ai comparé ceux-ci et j'ajouterais les captures d'écran, mais les commentaires ne prennent pas en charge l'ajout d'images; vous pouvez jeter un œil aux photos dans ma réponse. Cependant, cela peut différer avec les versions du navigateur, donc fournir des captures d'écran avec des annotations contenant des versions du navigateur serait utile.
YakovL
Visitez la page à laquelle j'ai lié dans différents navigateurs.
Vladimir Kornea
Alors je l'ai fait, n'est-ce pas? :) Vous ne voyez pas la différence? imagebin.ca/v/50stCZZGl7Ug imagebin.ca/v/50stNBiv29Ks Dans FireFox, ils sont parfaitement alignés, dans Chrome la case à cocher concerne la ligne de base (en passant, vous pouvez utiliser des mentions via @ si vous êtes intéressé par des réponses plus rapides)
YakovL
3

input[type=checkbox]
{
    vertical-align: middle;
} 
<input id="testCheckbox" name="testCheckbox" type="checkbox">
<label for="testCheckbox">I should align</label>

Premier
la source
2

Je laisse généralement une case à cocher sans étiquette, puis je fais de son "étiquette" un élément distinct. C'est une douleur, mais il y a tellement de différences entre les navigateurs entre la façon dont les cases à cocher et leurs étiquettes sont affichées (comme vous l'avez remarqué) que c'est la seule façon dont je peux me rapprocher de contrôler à quoi tout ressemble.

Je finis également par le faire dans le développement de winforms, pour la même raison. Je pense que le problème fondamental avec le contrôle de case à cocher est qu'il s'agit vraiment de deux contrôles différents: la case et l'étiquette. En utilisant une case à cocher, vous laissez le soin aux implémenteurs du contrôle de décider comment ces deux éléments sont affichés côte à côte (et ils se trompent toujours, où mauvais = pas ce que vous voulez).

J'espère vraiment que quelqu'un aura une meilleure réponse à votre question.

MusiGenesis
la source
2

CSS:

.threeCol .listItem {
    width:13.9em;
    padding:.2em;
    margin:.2em;
    float:left;
    border-bottom:solid #f3f3f3 1px;
}
.threeCol input {
    float:left;
    width:auto;
    margin:.2em .2em .2em 0;
    border:none;
    background:none;
}
.threeCol label {
    float:left;
    margin:.1em 0 .1em 0;
}

HTML:

<div class="threeCol">
    <div class="listItem">
        <input type="checkbox" name="name" id="id" value="checkbox1" />
        <label for="name">This is your checkBox</label>
    </div>
</div>

Le code ci-dessus placera vos éléments de liste dans trois colonnes et modifiera simplement les largeurs en fonction.

Philip Bevan
la source
2

Ce qui suit donne une cohérence parfaite au pixel près entre les navigateurs, même IE9:

L'approche est assez sensée, au point d'être évidente:

  1. Créez une entrée et une étiquette.
  2. Affichez-les sous forme de bloc pour pouvoir les faire flotter à votre guise.
  3. Définissez la hauteur et la hauteur de ligne sur la même valeur pour vous assurer qu'elles se centrent et s'alignent verticalement.
  4. Pour les mesures em , pour calculer la hauteur des éléments, le navigateur doit connaître la hauteur de la police de ces éléments, et elle ne doit pas elle-même être définie dans les mesures em.

Il en résulte une règle générale applicable à l'échelle mondiale:

input, label {display:block;float:left;height:1em;line-height:1em;}

Avec une taille de police adaptable par formulaire, jeu de champs ou élément.

#myform input, #myform label {font-size:20px;}

Testé dans les derniers Chrome, Safari et Firefox sur Mac, Windows, Iphone et Android. Et IE9.

Cette méthode est probablement applicable à tous les types d'entrée qui ne dépassent pas une ligne de texte. Appliquez une règle de type à votre convenance.

Henrik Erlandsson
la source
hm, cela semble bien quand l'étiquette commence par une lettre minuscule, mais si elle commence par une majuscule, c'est bien pire. Pourriez-vous ajouter un extrait ici?
YakovL
2

Je sais donc que cela a été répondu à plusieurs reprises, mais je pense que j'ai une solution beaucoup plus élégante que celles qui ont déjà été fournies. Et pas seulement 1 solution élégante, mais 2 solutions distinctes pour chatouiller votre envie. Cela dit, tout ce que vous devez savoir et voir est contenu dans 2 JS Fiddle's, avec des commentaires.


La solution n ° 1 repose sur la "Checkbox" native du navigateur donné, mais avec une torsion ... Elle est contenue dans un div qui est plus facile à positionner entre les navigateurs, avec un débordement: caché pour couper l'excès d'une case à cocher étirée de 1px (c'est donc vous ne pouvez pas voir les vilaines frontières de FF)

HTML simple: (suivez le lien pour revoir le css avec des commentaires, le bloc de code est pour satisfaire stackoverflow) http://jsfiddle.net/KQghJ/

<label><div class="checkbox"><input type="checkbox" /></div> Label text</label>

La solution n ° 2 utilise le "Checkbox Toggle Hack" pour basculer l'état CSS d'un DIV, qui a été correctement positionné dans le navigateur, et configuré avec un simple sprite pour les états des cases à cocher non cochées et cochées. Tout ce qui est nécessaire est d'ajuster la position d'arrière-plan avec ladite case à cocher Toggle Hack. À mon avis, c'est la solution la plus élégante, car vous avez plus de contrôle sur vos cases à cocher et radios, et vous pouvez garantir qu'elles se ressemblent dans tous les navigateurs.

HTML simple: (suivez le lien pour revoir le CSS avec des commentaires, le bloc de code est pour satisfaire StackOverflow) http://jsfiddle.net/Sx5M2/

<label><input type="checkbox" /><div class="checkbox"></div>Label text</label>

Si quelqu'un n'est pas d'accord avec ces méthodes, laissez-moi un commentaire, j'aimerais entendre des commentaires sur les raisons pour lesquelles d'autres n'ont pas trouvé ces solutions, ou s'ils l'ont, pourquoi je ne vois aucune réponse ici à leur sujet? Si quelqu'un voit une de ces méthodes échouer, ce serait bien de le voir aussi, mais celles-ci ont été testées dans les derniers navigateurs et s'appuient sur des méthodes HTML / CSS qui sont assez anciennes et universelles pour autant que je sache.

NinjaKC
la source
1

Ouais merci! Cela aussi m'a rendu fou pour toujours.

Dans mon cas particulier, cela a fonctionné pour moi:

input {
    width: 13px;
    height: 13px;
    padding: 0;
    margin:0;
    vertical-align: top;
    position: relative;
    *top: 1px;
    *overflow: hidden;
}
label {
    display: block;
    padding: 0;
    padding-left: 15px;
    text-indent: -15px;
    border: 0px solid;
    margin-left: 5px;
    vertical-align: top;
}

J'utilise reset.css, ce qui pourrait expliquer certaines des différences, mais cela semble bien fonctionner pour moi.

Jeff
la source
1

position: relative; a quelques problèmes dans IE avec z-index et des animations comme slideUp / slideDown de jQuery.

CSS:

input[type=checkbox], input[type=radio] {
    vertical-align: baseline;
    position: relative;
    top: 3px;
    margin: 0 3px 0 0;
    padding: 0px;
}
input.ie7[type=checkbox], input.ie7[type=radio] {
    vertical-align: middle;
    position: static;
    margin-bottom: -2px;
    height: 13px;
    width: 13px;
}

jQuery:

$(document).ready(function () {
    if ($.browser.msie && $.browser.version <= 7) {
        $('input[type=checkbox]').addClass('ie7');
        $('input[type=radio]').addClass('ie7');
    }
});

Le style a probablement besoin de modifications en fonction de la taille de police utilisée dans <label>

PS:
J'utilise ie7js pour faire fonctionner le CSS dans IE6.

Bob Fanger
la source
1

Utilisez simplement vertical-align: sub, comme pokrishka l'a déjà suggéré.

Violon

Code HTML:

<div class="checkboxes">
    <label for="check1">Test</label>
    <input id="check1" type="checkbox"></input>
</div>

Code CSS:

.checkboxes input {
    vertical-align: sub;
}
Marco Sulla
la source
1

Solution simple:

<label style="display:block">
  <input style="vertical-align:middle" type="checkbox">
  <span  style="vertical-align:middle">Label</span>
</label>

Testé dans Chrome, Firefox, IE9 +, Safari, iOS 9+

Dylan Sharhon
la source