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

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

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

11 ответов


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

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


добавьте обработчик событий для ontouchstart в тег . Это заставляет CSS волшебно работать.

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

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

вы также можете использовать -webkit-tap-highlight-color CSS свойство в сочетании с установкой сенсорного события для настройки кнопок, чтобы вести себя подобно рабочему столу. на iOS, мышь события отправляются так быстро, что состояние down или active никогда не принимается. таким образом,:active псевдо-состояние запускается только тогда, когда на HTML-элементе установлено событие touch-например, когда 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 свойства CSS, как описано в вышеуказанной ссылке.)


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

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

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

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

однако я не знаю о последствиях этого для производительности, поэтому остерегаться.


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


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

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

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


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

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


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

впрочем, добавив:

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

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


этой у меня работает:

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

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

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

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

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

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

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

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


решение положиться на :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>

нет 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;
    }
  }

Если вы хотите использовать pure html / css tooltip

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

<!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>