Aligner les étiquettes dans le formulaire à côté de l'entrée

136

J'ai un scénario de forme très basique et connu dans lequel je dois aligner correctement les étiquettes à côté des entrées. Cependant, je ne sais pas comment faire.

Mon objectif serait que les étiquettes soient alignées à côté des entrées sur le côté droit. Voici un exemple d'image du résultat souhaité.

entrez la description de l'image ici

J'ai fait un violon pour votre commodité et pour clarifier ce que j'ai maintenant - http://jsfiddle.net/WX58z/

Fragment:

<div class="block">
    <label>Simple label</label>
    <input type="text" />
</div>
<div class="block">
    <label>Label with more text</label>
    <input type="text" />
</div>
<div class="block">
    <label>Short</label>
    <input type="text" />
</div>

Stan
la source

Réponses:

190

Une solution possible:

  • Donnez les étiquettes display: inline-block;
  • Donnez-leur une largeur fixe
  • Aligner le texte à droite

C'est:

label {
  display: inline-block;
  width: 140px;
  text-align: right;
}​
<div class="block">
    <label>Simple label</label>
    <input type="text" />
</div>
<div class="block">
    <label>Label with more text</label>
    <input type="text" />
</div>
<div class="block">
    <label>Short</label>
    <input type="text" />
</div>

JSFiddle

bfavaretto
la source
4
Comment faire fonctionner cela si certaines des étiquettes sont des cases à cocher ou des boutons radio? Les étiquettes de ces éléments se retrouvent avec la même largeur fixe que les étiquettes de zone de texte, ce qui n'est pas souhaité. Existe-t-il un moyen de le faire sans une largeur fixe sur l'étiquette?
Rebecca Meritz le
@RebeccaMeritz Vous voulez dire quand le balisage a la case à cocher en premier, et l'étiquette après? Vous pouvez ajouter une classe aux deux et les styliser séparément. Vous devriez peut-être poser une nouvelle question à ce sujet.
bfavaretto le
2
Comment rendre cela réactif? Et comment faire face à i18n? Je veux dire que les étiquettes de texte ont une longueur différente dans différentes langues, donc je crains que ce réglage de remplissage à largeur fixe ne fonctionne pas si le texte est long.
Azimuth
@Azimuth De nos jours, vous voudrez peut-être utiliser la grille CSS à la place.
bfavaretto
1
il s'agit d'un marquage à largeur fixe, il doit être dynamique, basé sur la largeur maximale de l'étiquette.
Samyak Jain
27

Bien que les solutions ici soient réalisables, une technologie plus récente a permis ce que je pense être une meilleure solution. CSS Grid Layout nous permet de structurer une solution plus élégante.

Le CSS ci-dessous fournit une structure de «paramètres» à 2 colonnes, où la première colonne devrait être une étiquette alignée à droite, suivie d'un contenu dans la deuxième colonne. Un contenu plus compliqué peut être présenté dans la deuxième colonne en l'enveloppant dans un <div>.

[En remarque: j'utilise CSS pour ajouter le ':' qui suit chaque étiquette, car il s'agit d'un élément stylistique - ma préférence.]

/* CSS */

div.settings {
    display:grid;
    grid-template-columns: max-content max-content;
    grid-gap:5px;
}
div.settings label       { text-align:right; }
div.settings label:after { content: ":"; }
<!-- HTML -->

<div class="settings">
    <label>Label #1</label>
    <input type="text" />

    <label>Long Label #2</label>
    <span>Display content</span>

    <label>Label #3</label>
    <input type="text" />
</div>

David Rutherford
la source
1
Hé, pouvez-vous ajouter un violon s'il vous plaît?
Stan
Oui, j'ai mis à jour la réponse pour utiliser des extraits.
David Rutherford
Avec quelle version et plateforme de Chrome rencontrez-vous des problèmes?
David Rutherford
1
Solution optimale! Fonctionne bien maintenant dans Chrome 73.
Philipp Michalski
Impressionnant! Si vous remplacez la définition des colonnes ci-dessus par grid-template-columns: max-content 1fr;, la deuxième colonne utilisera toute la largeur restante. C'est pour moi le Saint Graal de telles mises en page, où aucune colonne ou largeur de contenu ne doit être spécifiée, et tout s'intègre parfaitement dans l'espace disponible, automatiquement.
jeff-h
12

A répondu à une question comme celle-ci auparavant, vous pouvez consulter les résultats ici:

Créer un formulaire pour avoir des champs et du texte côte à côte - quelle est la manière sémantique de le faire?

Donc, pour appliquer les mêmes règles à votre violon, vous pouvez utiliser display:inline-blockpour afficher votre étiquette et vos groupes d'entrée côte à côte, comme ceci:

CSS

input {
    margin-top: 5px;
    margin-bottom: 5px;
    display:inline-block;
    *display: inline;     /* for IE7*/
    zoom:1;              /* for IE7*/
    vertical-align:middle;
    margin-left:20px
}

label {
    display:inline-block;
    *display: inline;     /* for IE7*/
    zoom:1;              /* for IE7*/
    float: left;
    padding-top: 5px;
    text-align: right;
    width: 140px;
}

violon mis à jour

Andres Ilich
la source
C'est une très bonne solution, à part le fait que vous devez coder en dur la largeur des étiquettes. Si une nouvelle étiquette est trop longue, la mise en page est interrompue. On dirait qu'il devrait y avoir une solution plus robuste?
mattstuehler
8

J'utilise quelque chose de similaire à ceci:

<div class="form-element">
  <label for="foo">Long Label</label>
  <input type="text" name="foo" id="foo" />
</div>

Style:

.form-element label {
    display: inline-block;
    width: 150px;
}
Mike G
la source
4

Vous pouvez également essayer d'utiliser flex-box

<head><style>
body {
    color:white;
    font-family:arial;
    font-size:1.2em;
}
form {
    margin:0 auto;
    padding:20px;
    background:#444;
}
.input-group {
    margin-top:10px;
    width:60%;
    display:flex;
    justify-content:space-between;
    flex-wrap:wrap;
}
label, input {
    flex-basis:100px;
}
</style></head>
<body>

<form>
    <div class="wrapper">
        <div class="input-group">
            <label for="user_name">name:</label>
            <input type="text" id="user_name">
        </div>
        <div class="input-group">
            <label for="user_pass">Password:</label>
            <input type="password" id="user_pass">
        </div>
    </div>
</form>

</body>
</html>
user6797117
la source
C'est joli, mais pas du tout ce qu'il a demandé. Voir la photo en op
phorgan1
3

Je sais que c'est un vieux fil, mais une solution plus simple serait d'intégrer une entrée dans l'étiquette comme ceci:

<label>Label one: <input id="input1" type="text"></label>

Robert
la source
Je cherchais une solution pour cela (inclure l'entrée à l'intérieur de l'étiquette) mais avec du texte aligné
Natim
0

Voici la largeur des étiquettes génériques pour toutes les étiquettes de formulaire. Rien ne fixe la largeur.

appelez la calculatrice setLabelWidth avec toutes les étiquettes. Cette fonction chargera toutes les étiquettes sur l'interface utilisateur et découvrira la largeur maximale des étiquettes. Appliquez la valeur de retour de la fonction ci-dessous à toutes les étiquettes.

     this.setLabelWidth = function (labels) {
            var d = labels.join('<br>'),
                dummyelm = jQuery("#lblWidthCalcHolder"),
                width;
            dummyelm.empty().html(d);
            width = Math.ceil(dummyelm[0].getBoundingClientRect().width);
            width = width > 0 ? width + 5: width;
            //this.resetLabels(); //to reset labels.
            var element = angular.element("#lblWidthCalcHolder")[0];
            element.style.visibility = "hidden";
            //Removing all the lables from the element as width is calculated and the element is hidden
            element.innerHTML = "";
            return {
                width: width,
                validWidth: width !== 0
            };

        };
Samyak Jain
la source
0

Vous pouvez faire quelque chose comme ceci:

HTML:

<div class='div'>
<label>Something</label>
<input type='text' class='input'/>
<div>

CSS:

.div{
      margin-bottom: 10px;
      display: grid;
      grid-template-columns: 1fr 4fr;
}

.input{
       width: 50%;
}

J'espère que cela t'aides ! :)

Rakonjac
la source