Как выровнять чекбокс и текст css
Перейти к содержимому

Как выровнять чекбокс и текст css

  • автор:

Как выровнять чексбоксы с их метками в одну строку

введите сюда описание изображения

Есть CheckBoxList .
Проблема в том что если ListItem (текст) много слов то текст отображается одну строку ниже своего чекбокса
Если у некоторых чекбоксов у которых текста меньше отражается нормально
Как решить проблему буду признателен за любые советы
Скрин к примеру так отображается:

Отслеживать
задан 8 дек 2016 в 5:03
1,217 1 1 золотой знак 14 14 серебряных знаков 26 26 бронзовых знаков
А можно код, пожалуйста, и сделать его запускаемым?
8 дек 2016 в 8:22

@Vadim Ovchinnikov, ползуюсь bootstrap, там изменил display:inline-block на inline, стал норм отражать

8 дек 2016 в 8:45
@Vadim Ovchinnikov, хочу сделать это для моего отдельного checkbox-а
8 дек 2016 в 8:46

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

Чтобы ничего не съезжало и выглядело аккуратно, можно воспользоваться flex свойствами. Это очень просто и отлично работает.

Суть в том чтобы контейнеру в котором содержится чекбокс и текст к нему (как правило это label) дать следующие свойства:

.checkbox-group

Запустите демку ниже и посмотрите, устраивает ли вас такой результат. Надеюсь что помог. Удачи!

.checkboxes < padding: 5px 10px; max-width: 320px; width: 400px; border: 3px solid cornflowerblue; border-radius: 5px; >.checkbox-group < display: flex; flex-direction: row; justify-content: flex-start; align-items: flex-start; >.checkbox-group:not(:last-of-type) < margin-bottom: 10px; >.checkbox < cursor: pointer; >.label

Как выровнять checkbox и label?

Подскажите, как сделать, чтобы чекбоксы были по центру по вертикали относитньно label.
vertical-align: middle не помогает.

5e0e2bd498c3b359145696.jpeg

.flex-inner < display: flex; flex-wrap: wrap; list-style: none; >.flex-inner li < margin-top: 10px; >.flex-inner < flex-direction: column; >.flex-inner > li > label < margin-left: 10px; >.flex-inner>li>input
  • Вопрос задан более трёх лет назад
  • 5721 просмотр

Как выровнять чекбокс и текст css

Тема старая и уже, как выяснилось, подзабытая.

Недавно у меня была короткая работа по разработке ТЗ на модернизацию давно существующего проекта. И, в частности дело касалось стилизации пресловутых . Выяснилось, что исполнитель, программист «на все руки» даже не понял, что я ему на словах объяснял как это сделать. Пришлось делать примеры и, как результат, появился этот текст.

Напомню, что сейчас checkbox и radiobox разные сайты изображают по-разному. Бывает, что не отмеченный input сразу и не разглядишь – такой он «дизайнерский красивый», а у последних версий Chrome выбранные checkbox стали гнусного цвета циан.

Итак, ситуация

Есть три компании, которые используют некий программный продукт, связанный с заказами, бухгалтерией, складом и пр. Работа с заказчиками, партнерами, исполнителями и пр.

Маркетологи и рекламщики тоже его используют. Что эта система делает – неважно, на чем написано – неважно.

А важно, что на сайте этого продукта есть много страниц с формами, на которых много input checkbox и radio.

Жалобы сотрудников

Директор: На большом экране плохо видно и незаметны «крыжики».
Главбух: На моем компе «крыжики» выглядят так, у сотрудниц иначе, дома тоже не так, а на планшете совсем иначе.
Маркетолог: А можно, так что бы некоторые не выбранные позиции были красными, а другие выбранные были зелеными?
И т.д., и т.п.

Итак, задача

  1. Минимальными затратами и минимальными изменениями исправить внешний вид checkbox и radiobox.
  2. Сделать стилизацию checkbox и radiobox для разных юзеров. Важно: это закрытый сайт, там «всё свои», «красоты» не нужны, а нужна эффективность восприятия.

Что нельзя

1. Серверную часть трогать нельзя.
2. Файлы javascript трогать нельзя, свой javascript вставлять нельзя.
3. Файлы css трогать нельзя.

А что можно

1. Править html шаблоны.
2. Создать файл стилей для всех юзеров.
4. Создать файл стилей для конкретного юзера или группы юзеров.
А что сделали можно сразу посмотреть на codepen.io, но лучше почитать дальше.

Предварительное изучение показало

1. Почти все имеют поле name, а которые не имеют, то у них есть id.
2. Все имеют поле name, некоторые имеют id.
3. Соответственно, в css к checkbox можно обращаться как по id, так и по name. К radio – или по id, или по номеру потомка у родителя.

Фрагменты исходного кода:

/* вариант 1 */  Некий текст /* вариант 2 */  Некий текст 
Некий текст
/* вариант 3 */ . . /* вариант 4 */

Так исправим код:

/* вариант 1 */   /* вариант 2 */  
.
/* вариант 3 */ . . /* вариант 4 */

Всё тоже самое и для , класс у LABEL тот же.

Что конкретно сделали?

  1. Каждый input (корме варианта 3) обернули тэгом LABEL с нашим классом. Варианту 3 просто добавили класс.
  2. Сразу после input вставили пустой тэг S. Так как сам input будет не видим, то это тэг будет визуализировать это input.
  3. Сопроводительный текст обернули тэгом SPAN (кроме варианта 4). Этот тэг понадобиться, когда будем решать вопрос выравнивания визуального input относительно этого текста.
  4. Варианту 4 добавили еще класс, что бы не осуществлять это выравнивание, раз сопроводительный текст стоит в другой ячейки таблицы. Строго говоря, надо было бы сделать на оборот – вариантам 1-3 добавить класс, отвечающий за выравнивание. Но, вариантов 1-3 гораздо больше, чем 4-го и что бы не раздувать html сделано так.

Риторические вопросы и риторические же ответы

1. Зачем тэг S? Ну, не нравится S – можно использовать любой другой строчный элемент. Просто он должен быть, его можно стилизовать в зависимости от состояния предшествующего input.

2. Почему тэги S и SPAN без классов? Ну, зачем раздувать html? Тем более, что не очевидно, что одна из конструкций ниже будет «работать» медленнее другой.

 .new-input > S < >.new-input > .new-input-S <> 

3. Как вы догадались, мне не нравятся идеи БЭМ, тем более идея «раздувать» html файл обилием упоминаний разных классов. В реальном проекте мы использовали только два класса – mni и mnio. :-))

Некоторые предварительные рассуждения и настройки css касательно box-sizing:border-box, нормализации LABEL, селекторов «A + B», «A ~ B» и «[attr]», псевдоклассов :checked, :disabled и ::before. Кто не уверен, что знает или хочет освежить знания смотрит под катом.

Предварительные рассуждения

1. Напомню, что в «старом» css (box-sizing:content-box) свойства width и height задают только ширину и высоту содержимого, а padding и border добавляются к этим значениям. box-sizing:border-box меняет схему так, что padding и border включаются в width и height.

2. Проверка показала, что в нашем случае используется старая модель, а менять «настройки» страниц запрещено. Не «наши» LABEL это простые строчные элементы, в них только текст. Поэтому стилизуем ВСЕ LABEL.

LABEL < box-sizing:border-box; cursor:pointer; user-select:none; >LABEL *, LABEL *::before, LABEL *::after

Т.е., ставим box-sizing:border-box для тэга LABEL, всем его потомкам. Заодно ставим курсор и запрещаем выделение текст (что бы не мешало клику).

3. Комбинация селекторов «A + B» означает, что стили будут применяться только к селектору B, если он следует сразу ПОСЛЕ селектора A, т.е. только для первого B. С другой стороны, «A ~ B» означает, что ко всем селекторам B после селектора A, т.е. для первого и последующих.
Естественно, всё в пределах одного «родителя».

Как это будем использовать?

   
/* 1 */ .new-input > INPUT + S <> .new-input > INPUT ~ SPAN <> /* 2 */ .new-input > INPUT:not(:checked) + S <> .new-input > INPUT:not(:checked) ~ SPAN <> /* 3 */ .new-input > INPUT:checked + S <> .new-input > INPUT:checked ~ SPAN <> /* 4 */ .new-input > INPUT:disabled + S <> .new-input > INPUT:disabled ~ SPAN <> /* 5 */ .new-input > INPUT[type="radio"] + S <> 

Первая группа – общие стили для тэгов S и SPAN.
Вторая группа – стили только когда INPUT НЕ выбран.
Третья – стили только когда INPUT выбран.
Четвертая – когда INPUT заблокирован.

И, наконец, пятая группа – общие стили для тэга S ТОЛЬКО, если он стоит после input radio.
Таким образом, можно изменять стили тэгов S и SPAN в зависимости от состояния input.

4. Поскольку у нас тэг S будет изображать из себя input, то самому input поставим display:none, его не будет видно, а тэг LABEL будет его переключать, а тэг S будет соответственно меняться. Почему не используем html свойство hidden у input? Потому, что на некоторых браузерах hidden у input «работает» не совсем верно, плюс не будем перегружать html файл.

Итак, начинаем визуализацию input

Пример N 1. Самый простой – используем алфавитные символы
html код тот же, а css будет такой:

/* s1 */ .new-input > INPUT + S::before < content: "c"; >/* s2 */ .new-input > INPUT:checked + S::before < content: "V"; >/* s3 */ .new-input > INPUT[type="radio"] + S::before < content: "r"; >/* s4 */ .new-input > INPUT[type="radio"]:checked + S::before < content: "X"; >/* s5 */ .new-input > INPUT:disabled + S::before < opacity: 0.5; >/* s6 */ .new-input > S < text-decoration: none; margin-left: 3px; margin-right: 6px; >/* s7 */ .new-input > S::before < display: inline-block; width: 1.25em; text-align: center; color: #fafafa; background-color: #37474f; >/* s8 */ .new-input > INPUT[type="radio"] + S::before

Тэг S буде визуализировать input. Но мы «разделим» его по функционалу: сам тэг S будет отвечать за размещение в LABEL и выравнивание относительно следующего SPAN.

А псевдоэлемент S::before разместится внутри тэга S и будет изображать из себя input.

Строка s1 определяет, какой символ будет помещен в S::before когда input не выбран. В принципе надо было бы написать «.new-input > INPUT:not(:checked) + S::before», но некоторые браузеры (например, IE), подобную конструкцию могут и не исполнить.
Строка s2 определяет символ, когда input выбран.
Строки s3 и s4 делают то же для input radio.
Строка s5 описывает, что будет если input заблокирован – в данном случае тэг S будет наполовину прозрачным.
Строка s6 определяет выравнивание, в данном случае дает отбивку слева и справа (только в этом примере). Плюс, убирает штатное перечеркивание.
Строка s7 делает квадратик, s8 превращает его в кружок для input radio.

Пример N 1 можно посмотреть на codepen.io. Там представлены нативные input и новые. Первые можно убрать.

Чуток подробнее про display: inline-block, font-size, line-height

Конченая высота строки текста определяется на основе заданных font-size, line-height. При единичном line-height – высота будет по font-size, при числовом line-height – высота будет по их произведению или, при указании единиц измерения для line-height – высоту определит максимальное значение. В примере указан line-height:1.25, поэтому и у S::before указано width:1.25em.

Для S::before указано display: inline-block – в этом случае S::before «внутри» себя будет блоком (можно указать ширину, высоту, рамки и пр.), а «снаружи» он останется строчным элементом. В дальнейшем об этом будет подробнее.

Может можно использовать специальные символы? Типа вот этих:
? ¦ ? ? 0 ? ??
Задать им нужный размер и всё. Нет?

Можно. Но не нужно. Ибо будет большой геморрой и танцы с бубнами по заданию нужного размера, выравнивания по вертикали, обрезке по высоте и прочее. Плюс, разные браузеры с этими символами работают по-разному.
Мы пошли другим путем. Хотя в финальном примере есть реализация этой идеи.

Пример N 2. «Рисуем» элементы input средствами css

html код тот же, а css будет такой:

/* s1 */ .new-input > S::before < content: ""; display: inline-block; width: 0.75em; height: 0.75em; border: 1px solid currentColor; padding: 2px; background-clip: content-box; border-radius: 20%; >/* s2 */ .new-input > INPUT[type="radio"] + S::before < border-radius: 50%; >/* s3 */ .new-input > INPUT:checked + S::before < background-color: currentColor; >/* s4 */ .new-input > INPUT:disabled + S::before < opacity: 0.5; >/* s5 */ .new-input > S

Строка s1 определяет S::before для визуализации input. Это будет inline-block, ширина и высота которого установлена в 0.75em, что примерно равно высоте прописной буквы и зависит от font-size родителя. Задана тонкая рамка текущим цветом, внутренняя отбивка, небольшое скругление углов. И – самое важное! – установлено свойство background-clip:content-box. Это очень интересное свойство – если будет установлен background-color, то он закрасит только контентную часть и не затронет отбивку (padding). Что нам и надо.

Строка s2 для input типа radio делает S::before круглым.
Строка s3 для отмеченного input устанавливает для S::before background-color текущим цветом. Т.е., «рисует» внутри квадратик или кружок.
Строка s4 отрабатывает блокировку input, строка s5 дает отбивки слева и справа.

Преимущества этого метода

  1. Всё очень просто. Работает на всех браузерах. Даже у IE10 (в эмуляции у 11-го).
  2. Можно раскрашивать по своему усмотрению.
  3. Раз S::before это inline-block, то он сидит на попе базовой линии ровно и никуда с нее не слезает. Если он по высоте будет больше текста, то просто увеличит высоту строки и останется на базовой линии.
  4. Раз визуализация input находится внутри тэга S, то его можно легко позиционировать и выравнивать.
  5. Размеры S::before в em дают возможность задавать его размер относительно размера текста подписи. Можно, к примеру, поставить предельные значения высоты и ширины.

В основном в использовании размеров в em. Дело в том, что может возникнуть ситуация когда ширина и высота при расчете (из em в px) будет иметь дробное значение. На обычных компьютерах с обычным экраном округление может произойти не корректно. Например, размеры 12.8px на 12.8px у той же Мозилы могут стать как 13px на 12px. Тогда надо ставить фиксированные размеры. Хотя на современных мониторах и видеокартах, ноутбуках, на планшетах и смартфонах этого не происходит из-за того, что точка (пиксель) браузера состоит из нескольких пикселей экрана.

Пример N 2 можно посмотреть на codepen.io. Там представлены нативные input и новые. Первые можно убрать.
Итак, первую задачу – визуализацию input – выполнили. Переходим к избранной «раскраске».

Раскрашиваем input

html для примера:

   

К input типа checkbox будем обращаться по name, к radio по id.

Всё красим в синий

/* только input */ .new-input > INPUT[name="chb1"] + S, .new-input > INPUT#rb1 + S < color: #0091ea; >/* только text */ .new-input > INPUT[name="chb1"] ~ SPAN, .new-input > INPUT#rb1 ~ SPAN < color: #0091ea; >/* или всё */ .new-input > INPUT[name="chb1"] ~ *, .new-input > INPUT#rb1 ~ *

Помним о специфичности в css, эти стили будут более специфичны, чем базовые и сработают обязательно. Чем они отличаются от описанных выше? Тем, что применяются только к избранным input – к тем, что имеет указанное значение name и id.

Тут всё хорошо кроме того, что не выбранные input будут не очень хорошо глядеться – тонкая синяя рамка мало заметна.

Красим в зеленый, когда input выбран

/* только input */ .new-input > INPUT[name="chb1"]:checked + S, .new-input > INPUT#rb1:checked + S < color: #00c853; >/* только text */ .new-input > INPUT[name="chb1"]:checked ~ SPAN, .new-input > INPUT#rb1:checked ~ SPAN < color: #00c853; >/* или всё */ .new-input > INPUT[name="chb1"]:checked ~ *, .new-input > INPUT#rb1:checked ~ *

Первый вариант, на мой взгляд, не очень хорош – зеленым будут и рамка, и внутренний квадратик/кружок. Можно раскрасить только его.

/* только input и только внутри */ .new-input > INPUT[name="chb1"]:checked + S::before, .new-input > INPUT#rb1:checked + S::before

Красим в красный, когда input НЕ выбран

/* только input */ .new-input > INPUT[name="chb1"]:not(:checked) + S, .new-input > INPUT#rb1:not(:checked) + S < color: #d50000; >/* только text */ .new-input > INPUT[name="chb1"]:not(:checked) ~ SPAN, .new-input > INPUT#rb1:not(:checked) ~ SPAN < color: #d50000; >/* или всё */ .new-input > INPUT[name="chb1"]:not(:checked) ~ *, .new-input > INPUT#rb1:not(:checked) ~ *

Логика понятна? Можно и дальше делать более сложные конструкции.

Например, при не выбранном input текст должен быть красным и жирным, а при выбранном внутренний элемент input и текст должен быть зеленым. Элементарно!

/* текст, когда нет выбора */ .new-input > INPUT[name="chb1"]:not(:checked) ~ SPAN, .new-input > INPUT#rb1:not(:checked) ~ SPAN < color: #d50000; font-weight: bold; >/* внутренний элемент input, когда выбран */ .new-input > INPUT[name="chb1"]:checked + S::before, .new-input > INPUT#rb1:checked + S::before < background-color: #00c853; >/* текст, когда выбран */ .new-input > INPUT[name="chb1"]:checked ~ SPAN, .new-input > INPUT#rb1:checked ~ SPAN

А, к примеру, надо обработать целую группу input (10-15 штук). Что бы не писать кучу строк можно найти их общего родителя (.parent_element) и сократить условие.

.parent_element > .new-input > INPUT:not(:checked) ~ SPAN < color: #d50000; font-weight: bold; >.parent_element > .new-input > INPUT:checked + S::before < background-color: #00c853; >.parent_element > .new-input > INPUT:checked ~ SPAN

Всё можно посмотреть в финальном примере на codepen.io

Вот, вроде как, и всё. Осталось только «почесать родимые пятна» перфекциониста – проблемы выравнивания.

Выравнивание визуального input и сопроводительного текста

Для начала напомню общеизвестные вещи на тему размещения текста, форматирования и прочего. Всё под катом.

Общеизвестные вещи

Буду стараться не применят специальные термины, ибо в дизайне, верстке и css они иногда отличаются. Всё простыми словами.

1. Свойство font-size не определяет размер букв, а только размер знакоместа. Есть базовая линия (baseline), по которой расположены «нормальные» буквы. У «ненормальных» – g ц – нижние элементы «свисают» ниже её. Есть линия капители (cap height) – это верхняя граница «нормальной» прописной (заглавной) буквы. У «ненормальных» – Ё Й – верхние элементы «вылезают» выше её. Иными словами, размер прописной буквы это расстояние от базовой линии до капители, а знакоместо это чуть больше сверху и снизу. Обычно в «нормальных» шрифтах высота капители это 75% от высоты знакоместо. К примеру, font-size:16px, а размер буквы Н у шрифта Arial будет 12px. Но, бывают «специалисты» у шрифтов которых всё не так.

2. Свойство line-height определяет высоту строки. Если его вычисленное значение больше, чем указано в font-size, то браузер разместит текст так, что бы нормальная прописная буква была по середине высоты строки. Есть нюансы, но тут они не важны.

3. Соответственно, в нашем случае тэги S и SPAN должны иметь одинаковые значения font-size и line-height желательно заданные где-то выше у родителей. В нашем случае в примерах font-size:16px и line-height:1.25. Поэтому в примере N1 у S::before ширина указана 1.25em, а высота у него определяется автоматически. А в примере N2 (и финальный пример) – у S::before ширина и высота 0.75em, что бы был по высоте с прописную букву. Задав другое значение font-size ничего менять не надо. Естественно, эту величину надо подогнать под конкретный шрифт.

4. Если перед текстом стоит какая-то квадратная или круглая «штучка», то любой дизайнер скажет, что она должна быть по высоте с прописную букву. А отбивка между ними должна быть в определенных процентах от размера шрифта. Если высота меньше высоты буквы, то она должна быть визуально значительно меньше, но не меньше 50%. Если больше, то тоже визуально значительно больше, но не больше 150%. А вот чуть-чуть, на пару пикселей больше/меньше – это ужас-ужас! Ну, и расположена эта штучка должна быть на базовой линии или по середине без всяких там чуть-чуть.

Зачем я это упомянул? А затем, что перфекционисту глаза режет, когда input криво стоит рядом с текстом — или прилипает, или далеко, или чуть меньше, или чуть больше. Мы так делать не должны!

Что будет, если сопроводительный текст в SPAN будет выведен в две или три строки? Очевидно, что он «залезет» под input. Это не красиво, надо исправить.

Один древний метод такой: тэгу S делаем float:left, а тэгу SPAN display:block и overflow:hidden.

Получится колонка текста. Подразумевается, что у кого-то из них будет соответствующий margin, что даст отбивку между ними. Ну, ещё добавляется геморрой с прекращением float после SPAN. Мы пойдем современным путем – применим flexbox. Он тут совершенно к месту.

.new-input < display: flex; flex-direction: row; align-items: start; >.new-input > S < margin-right: 4px; flex: 0 0 auto; >.new-input > SPAN

В этом случае тэг LABEL (который .new-input) будет flex, S и SPAN будут блоками, разместятся вверху LABEL. Текст в SPAN в случае необходимости будет в несколько строк. Вот из-за этого визуальный input описали в S::before. Независимо от высоты SPAN S::before будет расположен на одной базовой линии с первой строкой SPAN. Как вариант можно было указать align-items:center – тогда при однострочном SPAN визуальный input был бы вверху, а при двух строках – посередине, а при трех – у второй строки. В финальном примере можно переключать расположение input.

Вот и всё

Надеюсь, было интересно и кому-нибудь полезно. Прошу, не сильно меня ругать – это мой первый опыт на Хабр.

Пример N 1 – просто демонстрация взаимодействия изменения input и соседнего элемента.

Пример N 2 – визуализация input средствами css, как основа решения.

Про конкретную реализацию

Там были обширные формы, где блоки полей возможные для правки конкретным пользователям выделялись слабым фоном, а остальным input имели свойство disabled и служили только для информации. Поэтому стиль «.new-input > INPUT:disabled + S::before» не применяли.

UPD

В ответ на комментарии Пример N 3.
Там работает поддержка клавиш и фокуса для скрытого input.

К сожалению, не доступен сервер mySQL

Как выровнять чекбокс по первой строке текста из двух строк?

Уважаемые мастера CSS подскажите как выровнять чекбокс по первой строке?
К сожалению я использую не нативный чекбокс, а вот эту библиотеку https://element.eleme.io/ для vue js.

В итоге на выходе получается такой html:

5d1ef8ab26abd625716611.png

У меня это выглядит так.

Ширина p будет ограничена и переносы по-любому нужны!
Как видите выравнивание при переносе строки ( white-space: normal;)
самого чекбокса идет по нижней строке.
Как сделать чтобы выравнивание шло по верхней строке?
Если ставлю
.el-checkbox__label white-space: normal;
vertical-align: top;
>
то чекбокс поднимается на верх, но съезжает в самый верх label и находится не на одной оси со строкой:

5d1efaae215b3806616771.png

На codepen подключил стили из element ui примерно тоже что и у меня рисует:
https://codepen.io/alex-buki/pen/YojMdZ

  • Вопрос задан более трёх лет назад
  • 1948 просмотров

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *