CSS селектор для помеченной метки переключателя


221

Можно ли применить стиль css (3) к метке отмеченного переключателя?

У меня есть следующая разметка:

<input type="radio" id="rad" name="radio"/>
<label for="rad">A Label</label>

Я надеялся, что

label:checked { font-weight: bold; }

будет что-то делать, но, увы, нет (как я и ожидал).

Есть ли селектор, который может достичь такой функциональности? Вы можете использовать div и т. Д., Если это поможет, но лучшим решением будет использование атрибута «for».

Следует отметить, что я могу указать браузеры для своего приложения, поэтому, пожалуйста, лучше всего из класса css3 и т. Д.

Ответы:


362

попробуйте +символ: это соседний брат и сестра комбинатор. Он объединяет в себе две последовательности простых селекторов, имеющих одного и того же родителя, и вторая должна идти НЕМЕДЛЕННО после первой.

В качестве таких:

input[type="radio"]:checked+label{ font-weight: bold; } 
 //a label that immediately follows an input of type radio that is checked 

очень хорошо работает для следующей разметки:

<input id="rad1" type="radio" name="rad"/><label for="rad1">Radio 1</label>
<input id="rad2" type="radio" name="rad"/><label for="rad2">Radio 2</label>

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

Пример:

input[type="radio"]:checked+label { font-weight: bold; }
<input id="rad1" type="radio" name="rad"/><label for="rad1">Radio 1</label>
<input id="rad2" type="radio" name="rad"/><label for="rad2">Radio 2</label>


11
Есть ли в любом случае, чтобы сделать это, но с этикеткой, являющейся предшествующим элементом EG:<label for="rad1">Radio 1</label><input id="rad1" type="radio" name="rad">
Nathan Koop

17
Вы можете использовать тильду, ~чтобы выбрать элементы одного уровня , которые не обязательно соседствуют. css-tricks.com/child-and-sibling-selectors
Мартин

1
Спасибо, это только помогло мне создать "радио-кнопки изображения" без JS.
KillerX

9
Стоит отметить, что это не будет работать в IE 8, так как :checkedселектор не поддерживается .
Марк Эмери

2
@Martin На всякий случай, если вам интересно, на самом деле это не сработает в вашем случае, так как ярлык все еще должен следовать за вводом. Разница между «+» и «~» заключается в том, является ли метка непосредственно смежной или вообще прилагательной: является ли метка следующим элементом или просто одним из следующих элементов.
Njord

127

Я знаю, что это старый вопрос, но если вы хотите иметь <input>детей, <label>а не разделять их, вот простой способ CSS, которым вы могли бы это сделать:

:checked + span { font-weight: bold; }

Затем просто оберните текст с <span>:

<label>
   <input type="radio" name="test" />
   <span>Radio number one</span>
</label>

Смотрите это на JSFiddle .


Превосходно. Это очень полезно, когда дело касается ситуации с бритвой <label>@Html.RadioButtonFor(..) someText<label>, я бросил <span>вокруг «someText», и это сработало как шарм. Спасибо!
S1r-Lanzelot

Ницца! Не думал об этом.
Мэтью Дин

Как раз то, что мне было нужно! Спасибо.
Райан

Что делать, если вы хотите стилизовать: активный ярлык с: флажок? Это не совсем решение.
Maciej Krawczyk

2
@MaciejKrawczyk Это не решение для вас, потому что ваш вариант использования совершенно другой. Если вы хотите стилизовать ярлык: active, вы можете просто сделать label:active { font-weight: bold; }. Смотрите: jsfiddle.net/Gbq8Z/608 (вау, я не могу поверить, что скрипка была разветвлена ​​608 раз).
Майк

22

Я забыл, где я впервые увидел упомянутое, но на самом деле вы можете вставлять свои метки в контейнер в другом месте, если у вас установлен for=атрибут. Итак, давайте проверим пример на SO:

* {
  padding: 0;
  margin: 0;
  background-color: #262626;
  color: white;
}

.radio-button {
  display: none;
}

#filter {
  display: flex;
  justify-content: center;
}

.filter-label {
  display: inline-block;
  border: 4px solid green;
  padding: 10px 20px;
  font-size: 1.4em;
  text-align: center;
  cursor: pointer;
}

main {
  clear: left;
}

.content {
  padding: 3% 10%;
  display: none;
}

h1 {
  font-size: 2em;
}

.date {
  padding: 5px 30px;
  font-style: italic;
}

.filter-label:hover {
  background-color: #505050;
}

#featured-radio:checked~#filter .featured,
#personal-radio:checked~#filter .personal,
#tech-radio:checked~#filter .tech {
  background-color: green;
}

#featured-radio:checked~main .featured {
  display: block;
}

#personal-radio:checked~main .personal {
  display: block;
}

#tech-radio:checked~main .tech {
  display: block;
}
<input type="radio" id="featured-radio" class="radio-button" name="content-filter" checked="checked">
<input type="radio" id="personal-radio" class="radio-button" name="content-filter" value="Personal">
<input type="radio" id="tech-radio" class="radio-button" name="content-filter" value="Tech">

<header id="filter">
  <label for="featured-radio" class="filter-label featured" id="feature-label">Featured</label>
  <label for="personal-radio" class="filter-label personal" id="personal-label">Personal</label>
  <label for="tech-radio" class="filter-label tech" id="tech-label">Tech</label>
</header>

<main>
  <article class="content featured tech">
    <header>
      <h1>Cool Stuff</h1>
      <h3 class="date">Today</h3>
    </header>

    <p>
      I'm showing cool stuff in this article!
    </p>
  </article>

  <article class="content personal">
    <header>
      <h1>Not As Cool</h1>
      <h3 class="date">Tuesday</h3>
    </header>

    <p>
      This stuff isn't nearly as cool for some reason :(;
    </p>
  </article>

  <article class="content tech">
    <header>
      <h1>Cool Tech Article</h1>
      <h3 class="date">Last Monday</h3>
    </header>

    <p>
      This article has awesome stuff all over it!
    </p>
  </article>

  <article class="content featured personal">
    <header>
      <h1>Cool Personal Article</h1>
      <h3 class="date">Two Fridays Ago</h3>
    </header>

    <p>
      This article talks about how I got a job at a cool startup because I rock!
    </p>
  </article>
</main>

Уф. Это было много для «образца», но я чувствую, что он действительно подчеркивает эффект и смысл: мы, безусловно, можем выбрать метку для проверенного элемента управления вводом, не имея при этом родного брата. Секрет заключается в том, чтобы inputтеги ребенка оставались только такими, какими они должны быть (в данном случае - только bodyэлементом) .

Поскольку labelэлемент фактически не использует :checkedпсевдоселектор, не имеет значения, что метки хранятся в header. Это имеет то дополнительное преимущество, что, так как headerэто элемент-брат, мы можем использовать ~общий селектор-брат для перемещения от input[type=radio]:checkedэлемента DOM к headerконтейнеру, а затем использовать селекторы потомок / потомок для доступа к labelсамим элементам , что позволяет им стилизовать их при соответствующие радиоблоки / флажки выбраны .

Мы можем не только стилизовать метки, но и стилизовать другой контент, который может быть потомком одноуровневого контейнера по отношению ко всем элементам input. А теперь, пока вы все так долго ждали, JSFIDDLE ! Идите туда, поиграйте с этим, заставьте это работать на вас, выясните, почему это работает, сломайте это, сделайте то, что вы делаете!

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


2
Это ответ на этот вопрос. Другие, хотя и правильные, по сути являются суперосновными. В то время как это решает что-то более сложное и интересное, за что можно было бы соблазниться.
morphles

Принятый ответ на этот вопрос имеет> 30x больше голосов, несмотря на ограничение, которое этот ответ полностью устраняет. В отличие от многих аналогично раскрученных постов, которые предполагают ошеломляющую информацию, это фактически соответствует требованию. Удивительная работа, большое спасибо.
naughtilus

1
@naughtilus - этот ответ полностью устраняет ограничение простого ответа, поскольку он явно определяет стили для каждого параметра. то есть шахта ограничивает вас наличием структурного соглашения; эта заставляет вас писать css для каждой кнопки-переключателя и результата.
Стивен

@ morphles simple! = "super basic": это решение более сложное, интересное и мощное - для этого точного кода; мой будет работать на всех страницах после 1 соглашения
Стивен

1

Если ваши входные данные являются дочерними элементами labelи у вас более одного ярлыка, вы можете объединить трюк @ Mike с Flexbox+ order.

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

HTML
<label class="switchLabel">
  <input type="checkbox" class="switch"/>
  <span class="left">Left</span>
  <span class="right">Right</span>
</label>
CSS
label.switchLabel {
  display: flex;
  justify-content: space-between;
  width: 150px;
}
.switchLabel .left   { order: 1; }
.switchLabel .switch { order: 2; }
.switchLabel .right  { order: 3; }

/* sibling selector ~ */
.switchLabel .switch:not(:checked) ~ span.left { color: lightblue }
.switchLabel .switch:checked ~ span.right { color: lightblue }

Смотрите это на JSFiddle .

примечание: родственный селектор работает только в пределах одного и того же родителя. Чтобы обойти это, вы можете скрыть ввод на верхнем уровне, используя взлом @Nathan Blair .


-1

Вы можете использовать немного jQuery:

$('input:radio').click(function(){
    $('label#' + $(this).attr('id')).toggleClass('checkedClass'); // checkedClass is defined in your CSS
});

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


3
Да ... конечно, это можно сделать с помощью javascript (frameworks), но это не так просто, как кажется. Что произойдет, если что-то еще уже будет отмечено? Какой сценарий удалит этот класс, если выбрано другое радио в той же группе? Это становится слишком сложным очень быстро. Я хочу использовать встроенную в браузер форму + CSS функциональность, потому что она будет работать каждый раз.
Стивен

4
Ваш селектор должен быть$('label[for="' + $(this).attr('id') + '"]').toggleClass();
Уэсли Мёрч

-3

ОБНОВИТЬ:

Это сработало только для меня, потому что наш существующий сгенерированный html был дурацким, генерируя labels вместе с radios и давая им оба checkedатрибута.

Не берите в голову, и большие взлеты для Brilliand для того, чтобы поднять это!

Если ваша метка является родственным элементом флажка (который обычно имеет место), вы можете использовать ~селектор брата и a label[for=your_checkbox_id]для его адреса ... или присвоить метке идентификатор, если у вас есть несколько меток (как в этом примере, где я используйте ярлыки для кнопок)


Пришел сюда в поисках того же самого - но в итоге нашел мой ответ в документах .

labelэлемент с checkedатрибутом может быть выбран следующим образом:

label[checked] {
  ...
}

Я знаю, что это старый вопрос, но, возможно, это кому-то поможет :)


5
И как ярлык должен быть проверен?
Brilliand

2
Эй, хороший улов. Это не так. Очевидно, у нас есть довольно дурацкий код, который генерирует метки вместе с переключателями и добавляет атрибут «флажок» к обоим при генерации html. Но это не совсем верно ... Так что это совершенно непригодно. Я отредактирую ответ, я понятия не имею, почему я получил за него голоса. Спасибо!
apprenticeDev
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.