: активный псевдокласс не работает в мобильном сафари

В Webkit на iPhone/iPad/iPod задание стиля для: активного псевдокласса для тега <a> не срабатывает при нажатии на элемент. Как я могу заставить это вызвать? Пример кода:

<style> 
a:active { 
    background-color: red;
}
</style>
<!-- snip -->
<a href="#">Click me</a>

Ответ 1

<body ontouchstart="">
    ...
</body>

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

Ответ 2

Как уже говорилось в других ответах, iOS Safari не вызывает псевдокласс :active если к элементу не присоединено событие касания, но пока это поведение было "волшебным". Я наткнулся на эту маленькую рекламу в Библиотеке разработчиков Safari, которая объясняет это (выделение мое):

Вы также можете использовать CSS-свойство -webkit-tap-highlight-color в сочетании с установкой события касания, чтобы настроить кнопки на поведение, аналогичное рабочему столу. На iOS события мыши отправляются так быстро, что неактивное или активное состояние никогда не принимается. Следовательно, псевдо-состояние :active запускается только в том случае, если для элемента HTML установлено событие касания, например, когда для элемента установлено ontouchstart следующим образом:

<button class="action" ontouchstart=""
        style="-webkit-tap-highlight-color: rgba(0,0,0,0);">
    Testing Touch on iOS
</button>

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

Другими словами, установка события ontouchstart (даже если оно пустое) явно указывает браузеру реагировать на сенсорные события.

На мой взгляд, это некорректное поведение, и, вероятно, оно восходит к тому времени, когда "мобильная" сеть вообще отсутствовала (посмотрите на эти скриншоты на связанной странице, чтобы понять, что я имею в виду), и все было ориентировано на мышь. Интересно отметить, что другие, более новые мобильные браузеры, такие как на Android, отображают псевдо-состояние ": active" на ощупь очень хорошо, без каких-либо взломов, подобных тому, что требуется для iOS.

(Примечание: если вы хотите использовать свои собственные стили в iOS, вы также можете отключить серое полупрозрачное поле по умолчанию, которое iOS использует вместо псевдо-состояния :active с помощью -webkit-tap-highlight-color свойство, как объяснено на той же связанной странице выше.)


После некоторых экспериментов ожидаемое решение установки события ontouchstart элемента <body> которому затем ontouchstart все события касания, не работает полностью. Если элемент отображается в окне просмотра при загрузке страницы, то он работает нормально, но прокрутка вниз и касание элемента, который был вне области просмотра, не вызывает псевдо-состояние :active как это должно быть. Итак, вместо

<!DOCTYPE html>
<html><body ontouchstart></body></html>

прикрепить событие ко всем элементам вместо того, чтобы полагаться на событие, всплывающее в теле (используя jQuery):

$('body *').on('touchstart', function (){});

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


РЕДАКТИРОВАТЬ: У этого решения есть один серьезный недостаток: даже прикосновение к элементу при прокрутке страницы активирует псевдо-состояние :active. Чувствительность слишком сильная. Android решает эту проблему, вводя очень небольшую задержку перед отображением состояния, которая отменяется при прокрутке страницы. В свете этого я предлагаю использовать это только для отдельных элементов. В моем случае я разрабатываю веб-приложение для использования в полевых условиях, которое представляет собой список кнопок для навигации по страницам и отправки действий. Так как в некоторых случаях вся страница содержит много кнопок, у меня это не сработает. Однако вы можете установить псевдо-состояние :hover чтобы заполнить его вместо этого. После отключения стандартного серого поля это работает отлично.

Ответ 3

Добавить обработчик событий для ontouchstart в тэге <a> . Это заставляет CSS работать магически.

<a ontouchstart="">Click me</a>

Ответ 4

Это работает для меня:

document.addEventListener("touchstart", function() {},false);

Примечание. Если вы сделаете этот трюк, то также стоит удалить цвет по умолчанию, выделенный касанием. Приложение Mobile Safari применяется с использованием следующего правила CSS.

html {
    -webkit-tap-highlight-color: rgba(0,0,0,0);
}

Ответ 5

По состоянию на 8 декабря 2016 года принятый ответ (<body ontouchstart="">...</body>) не работает для меня в Safari 10 (iPhone 5s): этот хак работает только для тех элементов, которые были видны при загрузке страницы.

Однако добавив:

<script type='application/javascript'>
  document.addEventListener("touchstart", function() {}, false);
</script>

в head работает так, как я хочу, с недостатком, что теперь все события касания во время прокрутки также запускают псевдо-состояние :active на затронутых элементах. (Если это проблема для вас, вы можете рассмотреть :hover FighterJet.)

Ответ 6

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

a:link
a:visited
a:hover
a:active

.. в этом порядке. Кроме того, если вы просто используете: active, добавьте ссылку: даже если вы не ставите ее.

Ответ 7

//hover for ios
-webkit-tap-highlight-color: #ccc;

Это работает для меня, добавьте в свой CSS элемент, который вы хотите выделить

Ответ 8

Я опубликовал инструмент, который должен решить эту проблему для вас.

На первый взгляд проблема выглядит просто, но на самом деле поведение прикосновений и кликов необходимо настраивать довольно широко, включая функции тайм-аута и такие вещи, как "что происходит при прокрутке списка ссылок" или "что происходит, когда вы нажимаете и затем переместите мышь/палец от активной области"

Это должно решить все сразу: https://www.npmjs.com/package/active-touch

Вам нужно будет либо иметь: активные стили, назначенные классу .active, либо выбрать собственное имя класса. По умолчанию script будет работать со всеми элементами ссылки, но вы можете перезаписать его собственным массивом селекторов.

Честная, полезная обратная связь и вклады очень ценятся!

Ответ 9

Решение состоит в том, чтобы полагаться на :target вместо :active:

<style> 
a:target { 
    background-color: red;
}
</style>
<!-- snip -->
<a id="click-me" href="#click-me">Click me</a>

Стиль будет активирован, когда якорь нацелен на текущий URL, который является устойчивым даже на мобильных устройствах. Недостаток в том, что вам нужна другая ссылка, чтобы очистить ссылку в URL. Полный пример:

a:target { 
    background-color: red;
}
<a id="click-me" href="#click-me">Click me</a>
<a id="clear" href="#">Clear</a>

Ответ 10

Для тех, кто не хочет использовать ontouchstart, вы можете использовать этот код

<script>
 document.addEventListener("touchstart", function(){}, true);
</script>

Ответ 11

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

  1. Переименованы объявления CSS, которые использовали :active в .active.
  2. Составил список всех затронутых элементов и добавил обработчики событий pointerdown/mousedown/touchstart, чтобы применить класс .active и обработчики событий pointerup/mouseup/touchend для его удаления. Использование jQuery:

    let controlActivationEvents = window.PointerEvent ? "pointerdown" : "touchstart mousedown";
    let controlDeactivationEvents = window.PointerEvent ? "pointerup pointerleave" : "touchend mouseup mouseleave";
    
    let clickableThings = '<comma separated list of selectors>';
    $(clickableThings).on(controlActivationEvents,function (e) {
        $(this).addClass('active');
    }).on(controlDeactivationEvents, function (e) {
        $(this).removeClass('active');
    });
    

Это было немного утомительно, но теперь у меня есть решение, которое менее уязвимо для взлома между версиями Apple OS. (А кому нужно что-то вроде этого взлома?)

Ответ 12

Нет 100%, связанных с этим вопросом, но вы можете использовать css sibling hack для достижения этого, а также

HTML

<input tabindex="0" type="checkbox" id="145"/>
<label for="145"> info</label>
<span> sea</span>

SCSS

input {
    &:checked + label {
      background-color: red;
    }
  }

Если вы хотите использовать чистую подсказку html/css

span {
  display: none;
}
input {
    &:checked ~ span {
      display: block;
    }
  }

Ответ 13

<!DOCTYPE html>

<html lang="en">

<head>
<meta charset="utf-8">

<title></title>

<style>
        a{color: red;}
        a:hover{color: blue;}
</style>
</head>

<body>

        <div class="main" role="main">
                <a href="#">Hover</a>
        </div>

</body>
</html>