Wyrównaj etykiety w formularzu obok danych wejściowych

136

Mam bardzo podstawowy i znany scenariusz formularza, w którym muszę poprawnie wyrównać etykiety obok danych wejściowych. Jednak nie wiem, jak to zrobić.

Moim celem byłoby wyrównanie etykiet obok danych wejściowych po prawej stronie. Oto przykład obrazu pożądanego wyniku.

wprowadź opis obrazu tutaj

Zrobiłem skrzypce dla twojej wygody i wyjaśnienia, co mam teraz - http://jsfiddle.net/WX58z/

Skrawek:

<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
źródło

Odpowiedzi:

189

Jedno możliwe rozwiązanie:

  • Podaj etykiety display: inline-block;
  • Daj im stałą szerokość
  • Wyrównaj tekst do prawej

To jest:

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
źródło
4
Jak to zrobić, jeśli niektóre etykiety to pola wyboru lub przyciski opcji? Etykiety tych elementów mają taką samą stałą szerokość jak etykiety pól tekstowych, co nie jest pożądane. Czy można to zrobić bez stałej szerokości etykiety?
Rebecca Meritz
@RebeccaMeritz Masz na myśli, kiedy znacznik ma najpierw pole wyboru, a potem etykietę? Możesz dodać klasę do obu i stylizować je oddzielnie. Być może powinieneś zadać nowe pytanie na ten temat.
bfavaretto
2
Jak sprawić, by to było responsywne? A jak sobie radzić z i18n? Chodzi mi o to, że etykiety tekstowe mają różną długość w różnych językach, dlatego obawiam się, że to ustawienie stałej szerokości wypełnienia nie zadziała, jeśli tekst jest długi.
Azymut
@Azimuth W dzisiejszych czasach możesz chcieć użyć siatki CSS.
bfavaretto
1
oznacza to stałą szerokość, powinno być dynamiczne, oparte na maksymalnej szerokości etykiety.
Samyak Jain
27

Chociaż rozwiązania tutaj są wykonalne, nowsza technologia stworzyła to, co uważam za lepsze rozwiązanie. Układ siatki CSS pozwala nam stworzyć bardziej eleganckie rozwiązanie.

Poniższy arkusz CSS zawiera 2-kolumnową strukturę „ustawień”, w której pierwsza kolumna ma być etykietą wyrównaną do prawej strony, a po niej część treści w drugiej kolumnie. Bardziej skomplikowaną treść można przedstawić w drugiej kolumnie, umieszczając ją w <div>.

[Na marginesie: używam CSS, aby dodać „:”, który śledzi każdą etykietę, ponieważ jest to element stylistyczny - moje preferencje.]

/* 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
źródło
1
Hej, czy możesz dodać skrzypce, proszę?
Stan
Tak, zaktualizowałem odpowiedź, aby korzystać z fragmentów.
David Rutherford,
Z jaką wersją i platformą Chrome masz problemy?
David Rutherford,
1
Optymalne rozwiązanie! Teraz działa dobrze w Chrome 73.
Philipp Michalski
Niesamowite! Jeśli zastąpisz powyższą definicję kolumn grid-template-columns: max-content 1fr;, druga kolumna wykorzysta całą pozostałą szerokość. To dla mnie święty Graal takich układów, w których nie trzeba określać szerokości kolumn ani treści, a wszystko automatycznie dopasowuje się idealnie do dostępnej przestrzeni.
jeff-h
12

Odpowiedziałeś wcześniej na takie pytanie, możesz spojrzeć na wyniki tutaj:

Tworzenie formularza tak, aby pola i tekst znajdowały się obok siebie - jaki jest semantyczny sposób, aby to zrobić?

Aby zastosować te same reguły do ​​swoich skrzypiec, możesz użyć display:inline-blockdo wyświetlania obok siebie etykiet i grup wprowadzania, na przykład:

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;
}

zaktualizowane skrzypce

Andres Ilich
źródło
To bardzo fajne rozwiązanie, poza tym, że trzeba na stałe zakodować szerokość etykiet. Jeśli nowa etykieta jest za długa - układ się psuje. Wydaje się, że powinno być solidniejsze rozwiązanie?
mattstuehler
8

Używam czegoś podobnego do tego:

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

Styl:

.form-element label {
    display: inline-block;
    width: 150px;
}
Mike G.
źródło
4

Możesz także spróbować użyć 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
źródło
To ładne, ale wcale nie to, o co prosił. Zobacz zdjęcie w op
phorgan1
3

Wiem, że to stary wątek, ale łatwiejszym rozwiązaniem byłoby osadzenie danych wejściowych w etykiecie w następujący sposób:

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

Robert
źródło
Szukałem rozwiązania dla tego (uwzględnij dane wejściowe wewnątrz etykiety), ale z wyrównanym tekstem
Natim
0

Oto ogólna szerokość etykiet dla wszystkich etykiet formularzy. Nic nie określa szerokości.

wywołaj kalkulator setLabelWidth ze wszystkimi etykietami. Ta funkcja załaduje wszystkie etykiety do interfejsu użytkownika i ustali maksymalną szerokość etykiety. Zastosuj zwracaną wartość poniższej funkcji do wszystkich etykiet.

     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
źródło
0

Możesz zrobić coś takiego:

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%;
}

Mam nadzieję że to pomoże ! :)

Rakonjac
źródło