Как удалить/игнорировать: наведите css стиль на сенсорных устройствах



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



a:hover {
color:blue;
border-color:green;
// etc. > ignore all at once for touch devices
}


так, (как) я могу удалить/игнорировать все CSS :hover объявления сразу (без необходимости знать каждый) для сенсорных устройств после их объявления?

2124   11  

11 ответов:

есть несколько решений для этой проблемы.

Quick'n'Dirty-удалить: наведите стили с помощью JS

вы можете удалить все правила CSS, содержащие :hover С помощью Javascript. Это имеет то преимущество, что не нужно касаться CSS и быть совместимым даже со старыми браузерами.

function hasTouch() {
    return 'ontouchstart' in document.documentElement
           || navigator.maxTouchPoints > 0
           || navigator.msMaxTouchPoints > 0;
}

if (hasTouch()) { // remove all :hover stylesheets
    try { // prevent exception on browsers not supporting DOM styleSheets properly
        for (var si in document.styleSheets) {
            var styleSheet = document.styleSheets[si];
            if (!styleSheet.rules) continue;

            for (var ri = styleSheet.rules.length - 1; ri >= 0; ri--) {
                if (!styleSheet.rules[ri].selectorText) continue;

                if (styleSheet.rules[ri].selectorText.match(':hover')) {
                    styleSheet.deleteRule(ri);
                }
            }
        }
    } catch (ex) {}
}

ограничения: таблицы стилей должны быть размещены на тот же домен (это означает отсутствие CDNs). Отключает зависания на mixed мышь и сенсорная устройства как поверхность, которая вредит UX.

CSS-only-use media queries

Поместите все ваши: наведите правила в @media блок:

@media (hover: hover) {
    a:hover { color: blue; }
}

или альтернативно, переопределите все ваши правила наведения (совместимые со старыми браузерами):

a:hover { color: blue; }

@media (hover: none) {
    a:hover { color: inherit; }
}

ограничения: работает только на iOS 9.0+, Chrome для Android или Android 5.0+ при использовании WebView. hover: hover ломает эффекты наведения на старых браузерах,hover: none необходимо переопределить все ранее определены правила CSS. Оба они несовместимо со смешанными устройствами мыши и сенсорного.

самый надежный-используйте специальный класс CSS и обнаруживайте прикосновение через JS

этот метод требует добавления всех правил наведения с body.hasHover. (или имя класса по вашему выбору)

body.hasHover a:hover { color: blue; }

The hasHover класс может быть добавлен с помощью hasTouch() из первого примера:

if (!hasTouch()) {
    document.body.className += ' hasHover';
}

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

function watchForHover() {
    var hasHoverClass = false;
    var container = document.body;
    var lastTouchTime = 0;

    function enableHover() {
        // filter emulated events coming from touch events
        if (new Date() - lastTouchTime < 500) return;
        if (hasHoverClass) return;

        container.className += ' hasHover';
        hasHoverClass = true;
    }

    function disableHover() {
        if (!hasHoverClass) return;

        container.className = container.className.replace(' hasHover', '');
        hasHoverClass = false;
    }

    function updateLastTouchTime() {
        lastTouchTime = new Date();
    }

    document.addEventListener('touchstart', updateLastTouchTime, true);
    document.addEventListener('touchstart', disableHover, true);
    document.addEventListener('mousemove', enableHover, true);

    enableHover();
}

watchForHover();

это должно работать в основном в любом браузере и включает/отключает стили наведения по мере необходимости. Попробуйте здесь:https://jsfiddle.net/dkz17jc5/19/

указатель адаптации на помощь!

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

a:link {
   color: red;
}

a:hover {
   color:blue;
}

@media (hover: none) {
   a:link {
      color: red;
   }
}

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

Примечание: имейте в виду, что поскольку основной вход (возможность) Surface PC-это мышь, он будет в конечном итоге синей ссылкой, даже если это отдельный экран (планшет). Броузеры будут (должны) всегда по умолчанию для возможности наиболее точного ввода.

Я имею дело с аналогичной проблемой в настоящее время.

есть два главная параметры, которые возникают у меня сразу: (1) проверка пользовательских строк или (2) поддержка отдельных мобильных страниц с использованием другого URL-адреса и выбор пользователями того, что лучше для них.

  1. если вы можете использовать интернет-язык клейкой ленты, такой как PHP или Ruby, вы можете проверить строка пользователей устройства, запрашивающего страницу, и просто служить то же самое содержание, но с <link rel="mobile.css" /> вместо обычного стиля.

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

A. Если вам позволено игнорировать старые браузеры, вам просто нужно добавить одно правило к обычному, немобильному css, а именно:EDIT: Erk. После некоторых экспериментов я обнаружил, что приведенное ниже правило также отключает возможность следовать ссылкам в WebKit-браузерах в дополнение к тому, чтобы просто отключить эстетические эффекты-см. http://jsfiddle.net/3nkcdeao/
таким образом, вам придется быть немного более избирательным в отношении того, как вы изменяете правила для мобильного случая, чем то, что я показываю здесь, но это может быть полезной отправной точкой:

* { 
    pointer-events: none !important; /* only use !important if you have to */
}

в качестве примечания, отключение событий указателя на родителе, а затем явное включение их на дочернем элементе в настоящее время вызывает любые эффекты наведения на родителя, чтобы снова стать активным, если дочерний элемент вводит :hover.
см.http://jsfiddle.net/38Lookhp/5/

B. Если вы поддерживаете устаревшие веб-рендеры, вам придется сделать немного больше работы по удалению любых правил, которые устанавливают специальные стили во время :hover. Чтобы сэкономить всем время, вы можете просто построить автоматизированный копирование + sedING команда, которую вы запускаете на стандартных таблицах стилей для создания мобильных версий. Это позволит вам просто написать / обновить стандартный код и стереть любые правила стиля, которые используют :hover для мобильной версии страницы.

  1. (I) в качестве альтернативы, просто сделать ваши пользователи знают, что у вас есть m.website.com для мобильных устройств в дополнение к вашим website.com. хотя субдомен является наиболее общий способ, вы также можете иметь некоторые другие предсказуемые изменения данного URL-адреса, чтобы позволить мобильным пользователям получить доступ к измененным страницам. На этом этапе вы должны быть уверены, что им не нужно изменять URL-адрес каждый раз, когда они переходят к другой части сайта.

опять же здесь, вы можете просто добавить дополнительное правило или два в таблицы стилей или быть вынуждены сделать что-то немного более сложное с помощью sed или подобную программу. Было бы, наверное проще всего применить :не к вашим правилам стиля, как div:not(.disruptive):hover {... где бы вы добавили class="disruptive" к элементам, делающим раздражающие вещи для мобильных пользователей, использующих js или серверный язык, вместо того, чтобы munging CSS.

  1. (II) вы можете фактически объединить первые два и (если вы подозреваете, что пользователь забрел в неправильную версию страницы) вы можете предложить, чтобы они переключались в/из дисплея мобильного типа или просто имели ссылку где-то, которая позволяет пользователям флоп назад и вперед. Как уже говорилось, запросы @media также могут быть чем-то, что можно использовать для определения того, что используется для посещения.

  2. (III) Если вы готовы к решению jQuery, как только вы знаете, какие устройства являются "сенсорными", а какие нет, вы можете найти CSS hover не игнорируется на устройствах с сенсорным экраном полезная.

попробуйте это:

@media (hover:<s>on-demand</s>) {
    button:hover {
        background-color: #color-when-NOT-touch-device;
    }
}

обновление: к сожалению, W3C удалил это свойство из спецификаций (https://github.com/w3c/csswg-drafts/commit/2078b46218f7462735bb0b5107c9a3e84fb4c4b1).

можно использовать Modernizr JS (см. Также это StackOverflow ответ), или сделать пользовательскую функцию JS:

function is_touch_device() {
 return 'ontouchstart' in window        // works on most browsers 
  || navigator.maxTouchPoints;       // works on IE10/11 and Surface
};

if ( is_touch_device() ) {
  $('html').addClass('touch');
} else {
  $('html').addClass('no-touch');
} 

до обнаружьте поддержку касания событие в браузере, а затем назначить обычный CSS свойство, пересекающее элемент с помощью html.no-touch класс, как это:

html.touch a {
    width: 480px;
}

/* FOR THE DESKTOP, SET THE HOVER STATE */
html.no-touch a:hover {
   width: auto;
   color:blue;
   border-color:green;
}

я столкнулся с той же проблемой (в моем случае с мобильными браузерами Samsung) и поэтому я наткнулся на этот вопрос.

спасибо Calsal это Я нашел то, что, как я считаю, исключит практически все настольные браузеры, потому что он, кажется, распознается мобильными браузерами, которые я пробовал (см. скриншот из скомпилированной таблицы: таблица обнаружения функции указателя CSS ).

MDN web docs государство, которое

указатель CSS @media функция может быть использована для применения стилей на основе является ли основной механизм ввода пользователя указательным устройством, и если да, то насколько это точно

.

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

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

Sass mixin:

@mixin hover-supported {    
    /* 
     * https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer 
     * coarse: The primary input mechanism includes a pointing device of limited accuracy.
     */
    @media not all and (pointer: coarse) {
        &:hover {
            @content;
        }
    }
}

a {
    color:green;
    border-color:blue;

    @include hover-supported() {
        color:blue;
        border-color:green;
    }
}

скомпилированный CSS:

a {
  color: green;
  border-color: blue;
}
@media not all and (pointer: coarse) {
  a:hover {
    color: blue;
    border-color: green;
  }
}

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

обновление: На момент написания этого обновления, 2018-08-23, и указал @DmitriPavlutin этот метод больше не работает с Firefox desktop.

Это также возможный обходной путь, но вам придется пройти через ваш css и добавить .no-touch класс перед вашими стилями наведения.

Javascript:

if (!("ontouchstart" in document.documentElement)) {
document.documentElement.className += " no-touch";
}

пример CSS:

<style>
p span {
    display: none;
}

.no-touch p:hover span {
    display: inline;
}
</style>
<p><a href="/">Tap me</a><span>You tapped!</span></p>

источник

P. s. но мы должны помнить, что на рынок выходит все больше и больше сенсорных устройств, которые также поддерживают ввод мыши одновременно.

Это может быть еще не идеальное решение (и это с jQuery), но, возможно, это направление / концепция для работы: как насчет того, чтобы сделать это наоборот? Это означает деактивацию состояний css: hover по умолчанию и активацию их, если событие mousemove обнаружено в любом месте документа. Конечно, это не работает, если кто-то деактивировал js. Что еще может говорить против того, чтобы сделать это таким образом?

может быть, как это:

CSS:

/* will only work if html has class "mousedetected" */
html.mousedetected a:hover {
   color:blue;
   border-color:green;
}

jQuery:

/* adds "mousedetected" class to html element if mouse moves (which should never happen on touch-only devices shouldn’t it?) */
$("body").mousemove( function() {
    $("html").addClass("mousedetected");
});

Это было полезно для меня: ссылке

function hoverTouchUnstick() {
    // Check if the device supports touch events
    if('ontouchstart' in document.documentElement) {
        // Loop through each stylesheet
        for(var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
            var sheet = document.styleSheets[sheetI];
            // Verify if cssRules exists in sheet
            if(sheet.cssRules) {
                // Loop through each rule in sheet
                for(var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
                    var rule = sheet.cssRules[ruleI];
                    // Verify rule has selector text
                    if(rule.selectorText) {
                        // Replace hover psuedo-class with active psuedo-class
                        rule.selectorText = rule.selectorText.replace(":hover", ":active");
                    }
                }
            }
        }
    }
}

по данным Jasons ответ мы можем обращаться только к устройствам, которые не поддерживают наведение с чистыми запросами css media. Мы также можем обращаться только к устройствам, которые поддерживают наведение, например moogals ответ в аналогичном вопросе, с @media not all and (hover: none). Это выглядит странно, но это работает.

Я сделал Sass mixin из этого для более легкого использования:

@mixin hover-supported {
    @media not all and (hover: none) {
        &:hover {
            @content;
        }
    }
}

следующее изменило бы цвет фона .container от красного до синего при наведении курсора для устройств, которые его поддерживают и остаются красными для сенсорных устройств:

.container {
    background-color: red;

    @include hover-supported() {
        background-color: blue;
    }
}

Это можно решить с помощью sass / scss и медиа-запроса с требуемой точкой останова.

.myclass {
    background-color: blue;
    &:hover {
        @media screen and (max-width: 320px) {
            background-color: red;
        }
    }
}

Comments

    Ничего не найдено.