: фокусировка на пользовательском радиовходе

У меня есть пользовательский стиль ввода радио, который реализован более или менее следующим образом:

<input type="radio" id="testradio" class="visuallyhidden custom-radio">
<label for="testradio">...</label>

.custom-radio + label:before {
  content: ""
  // Styling goes here
}

.custom-radio:focus + label:before {
  outline: 1px solid black;
]

Это отлично работает, за исключением одной ворчащей детали: стиль фокуса для навигации по клавиатуре. Я могу выбрать группу переключателей и использовать клавиши со стрелками, чтобы изменить выбранную, но контур фокуса по умолчанию не отображается, потому что тэг ввода скрыт.

Я попробовал добавить свой собственный стиль фокуса, как указано выше, но это ведет себя по-другому, чем стиль браузера по умолчанию. По умолчанию Chrome (и другие браузеры, которые я предполагаю), нарисует контур только тогда, когда вы выбираете клавиатуру для радиовходов, а не когда вы нажимаете на них. Тем не менее, стиль CSS: focus кажется применимым при нажатии на радиовход (также в этом случае, щелкая по метке), что выглядит очень плохо.

В основном, мой вопрос заключается в следующем: как применить стиль: focus к радиовходу, который полностью имитирует поведение браузера по умолчанию, т.е. не отображается с фокуса щелчка мыши? Или есть ли другой способ настроить этот радиовход, который поможет мне сохранить поведение по умолчанию?

Edit: Здесь JSFiddle демонстрирует, о чем я говорю. В первой строке вы можете щелкнуть переключатель, а затем перейти с помощью клавиш со стрелками - контур появится только при использовании клавиатуры. Во второй строке нажатие на переключатель сразу вызывает стиль фокуса.

http://jsfiddle.net/7Ltcks3n/1/

Ответы

Ответ 1

Я столкнулся с этой проблемой так долго, я получил решение

https://jsfiddle.net/hahkarthick/nhorqnvt/3/

input:focus, input:hover{
    outline: 2px auto rgb(229, 151, 0);
    outline-offset: -2px;
 }
<input id="inp" type=radio>radio1
<input type=radio>radio2
<input type=radio>radio3
<input type=radio>radio4
<input type=radio>radio5

Ответ 2

Проблема заключается в том, что, по-видимому, браузеры Blink поддерживают фокусировку на радиоэлементах после их нажатия, но Firefox и Safari этого не делают.

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

Рабочий пример:

var className = 'focus-radio-hide-ring';
var add = function() {
    document.documentElement.classList.add(className);
};
var remove = function() {
    document.documentElement.classList.remove(className);
};
window.addEventListener('mousedown', add, true);
window.addEventListener('touchstart', add, true);
window.addEventListener('keydown', remove, true);
.custom-radio {
	position: absolute;
	opacity: 0;
}
.custom-radio + label {
	cursor: pointer;
}
.custom-radio + label:before {
	content: "";
	display: inline-block;
	vertical-align: middle;
	width: 0.75em;
	height: 0.75em;
	margin-right: 0.25em;
	background: #EEEEEE;
	border: 1px solid #AAAAAA;
	border-radius: 50%;
}
.custom-radio:checked + label:before {
	background: #6666FF;
}

/* Add styles here: */ 
.custom-radio:focus + label:before {
	box-shadow: 0 0 4px 1px rgba(0, 0, 0, 1);
}
/* Add disable them again here: */ 
.focus-radio-hide-ring .custom-radio:focus + label:before {
	box-shadow: none;
}
<p><input placeholder="Tab from here"></p>

<input id="testradio" type="radio" class="custom-radio">
<label for="testradio">Example</label>

Ответ 3

Вы можете добиться этого, используя скрипты. Сначала вам понадобится привязка keypress к радио и добавьте стиль контура в этом обработчике всякий раз, когда радио становится сфокусированным или активным (путем добавления вашего класса пользовательского радио для активного ввода). так что вы можете опустить стиль контура с помощью мыши.

Ответ 4

Это не решит вашу проблему на данный момент, но на самом деле есть селектор, который делает именно то, что вам нужно: :focusring (https://github.com/w3c/csswg-drafts/pull/709). Сейчас он работает только в Firefox, но должен появиться и в других браузерах.

Вы можете использовать JS, например, sumankumarg, но вы также можете использовать границу поддельного ввода для отображения состояния фокусировки следующим образом: http://jsbin.com/rofawiginu/edit?html,css,output

Ответ 5

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

Демо-код ниже, подробнее в исходной статье: https://ghinda.net/article/mimic-native-focus-css/

.unreal-focus {
  outline-width: 2px;
  outline-style: solid;
  outline-color: Highlight;
}

/* WebKit gets its native focus styles.
 */
@media (-webkit-min-device-pixel-ratio:0) {
  .unreal-focus {
    outline-color: -webkit-focus-ring-color;
    outline-style: auto;
  }
}

Ответ 6

Я собрал фрагмент ниже, основываясь на исходном коде, а не на примере скрипта. Из того, что я собираю, вы пытаетесь заменить переключатель по умолчанию своим стильным элементом (label:before).

Поскольку не указано, как скрыты радиостанции по умолчанию, я просто использовал opacity: 0 и скорректировал положение элемента метки для его покрытия. Тот же эффект может быть достигнут путем перемещения радиостанции с экрана: position: absolute; top: -999; left -999; (или что-то подобное).

Я попытался использовать display: none и vibility: hidden на радиостанциях, но это проблема, потому что очевидно, что действие фокуса не срабатывает, когда они не видны.

Я также дал элементу label:before некоторый стиль, чтобы он отображался.

Чтобы решить проблему:

.custom-radio:focus + label:before {
  outline: 1px solid black;
  outline: 1px auto -webkit-focus-ring-color;
}

При нажатии метки outline:0 1px solid black; отображается схема по умолчанию. Это отлично работает для FF и IE, но для Chrome вам нужно изменить цвет на -webkit-focus-ring-color, потому что он использует синий цвет для контура радиосвязи.

.visuallyhidden {
  opacity: 0;
}
.custom-radio + label {
  position: relative;
  left: -25px;
  margin-right: -15px;
}
.custom-radio + label:before {
  content: "X";
  margin: 5px;
  // Styling goes here
}

.custom-radio:focus + label:before {
  outline: 1px solid black;
  outline: 1px auto -webkit-focus-ring-color;
}
<input type="radio" name="testradio" id="testradio1" class="visuallyhidden custom-radio">
<label for="testradio1">radio 1</label>
<input type="radio" name="testradio" id="testradio2" class="visuallyhidden custom-radio">
<label for="testradio2">radio 2</label>
<input type="radio" name="testradio" id="testradio3" class="visuallyhidden custom-radio">
<label for="testradio3">radio 3</label>