Jak usunąć / zignorować:najedź kursorem styl css na urządzeniach dotykowych

Chcę zignorować wszystkie :hover deklaracje CSS, jeśli użytkownik odwiedza naszą stronę za pomocą urządzenia dotykowego. Ponieważ :hover CSS nie ma sensu, i może być nawet niepokojące, jeśli tablet uruchamia go po kliknięciu/dotknięciu, ponieważ wtedy może się trzymać, dopóki element nie straci ostrości. Szczerze mówiąc, Nie wiem, dlaczego urządzenia dotykowe czują potrzebę wyzwalania :hover na pierwszym miejscu - ale to jest rzeczywistość, więc ten problem jest również rzeczywistością.

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

Więc (jak) mogę usunąć / zignorować wszystkie deklaracje CSS :hover od razu (bez konieczności znajomości każdego z nich) dla urządzeń dotykowych po ich zadeklarowaniu?

Author: Simon Ferndriger, 2014-05-27

11 answers

Istnieje wiele rozwiązań tego problemu.

Quick ' n ' dirty-remove :hover styles using JS

Możesz usunąć wszystkie reguły CSS zawierające :hover za pomocą Javascript. Ma to tę zaletę, że nie trzeba dotykać CSS i jest kompatybilny nawet ze starszymi przeglądarkami.

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) {}
}

Ograniczenia: arkusze stylów muszą być hostowane w tej samej domenie (oznacza to brak CDN). Wyłącza hovery na urządzeniach mixed mouse & touch Jak Surface, co boli UX.

CSS-only-use media queries

Umieść wszystkie zasady: hover w bloku @media:

@media (hover: hover) {
    a:hover { color: blue; }
}
Można też zastąpić wszystkie reguły hover (kompatybilne ze starszymi przeglądarkami):
a:hover { color: blue; }

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

Ograniczenia: działa tylko na iOS 9.0+, Chrome dla Androida lub Android 5.0+ podczas korzystania z WebView. hover: hover przerywa efekty hover w starszych przeglądarkach, hover: none wymaga nadpisania wszystkich wcześniej zdefiniowanych reguł CSS. Oba są niezgodne z mieszaną myszą i dotykiem urządzenia .

Najbardziej wytrzymały-użyj specjalnej klasy CSS i wykryj dotyk przez JS

Ta metoda wymaga poprzedzenia wszystkich reguł hover body.hasHover. (lub wybraną przez Ciebie nazwę klasy)

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

Klasa hasHover może być dodana za pomocą hasTouch() z pierwszego przykładu:

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

Ma to jednak ten sam problem z mieszanymi urządzeniami dotykowymi, co poprzednie przykłady, co prowadzi nas do ostatecznego rozwiązania. Włączanie efektów najazdu po przesunięciu kursora myszy, wyłączanie najazdu efekty po wykryciu dotyku.

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();

Powinno to działać w zasadzie w każdej przeglądarce i włącza / wyłącza style najazdu w razie potrzeby. Spróbuj tutaj: https://jsfiddle.net/dkz17jc5/19/

 67
Author: blade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-16 08:36:40

Adaptacja wskaźnika na ratunek!

Ponieważ to nie było dotykane przez jakiś czas, możesz użyć:

a:link {
   color: red;
}

a:hover {
   color:blue;
}

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

Zobacz to demo zarówno w przeglądarce stacjonarnej, jak i w przeglądarce telefonu . Obsługiwane przez nowoczesne urządzenia dotykowe .

Uwaga: Należy pamiętać, że ponieważ głównym wejściem (możliwością) komputera Surface PC jest mysz, będzie to niebieskie łącze, nawet jeśli jest to odłączony ekran (tablet). Przeglądarki będą (powinny) zawsze domyślne najbardziej możliwość precyzyjnego wprowadzania danych.

 28
Author: Jason T Featheringham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-25 07:08:05

Obecnie mam do czynienia z podobnym problemem.

Istnieją dwie główne opcje, które pojawiają się natychmiast: (1) sprawdzanie ciągów użytkowników lub (2) utrzymywanie oddzielnych stron mobilnych przy użyciu innego adresu URL i wybieranie przez użytkowników tego, co jest dla nich lepsze.

  1. Jeśli jesteś w stanie użyć języka internetowego, takiego jak PHP lub Ruby, możesz sprawdzić user string urządzenia żądającego strony i po prostu podać tę samą treść, ale zamiast tego <link rel="mobile.css" /> stylu normalnym.

Ciągi użytkowników zawierają informacje identyfikujące przeglądarkę, renderer, system operacyjny itp. Od Ciebie zależy, jakie urządzenia są "dotykowe", a nie dotykowe. Może być w stanie znaleźć te informacje dostępne gdzieś i mapować je do systemu.

O. jeśli masz prawo ignorować stare przeglądarki, wystarczy dodać jedną regułę do normalnego, Nie-mobilnego css, a mianowicie: EDIT : Erk. Po zrobieniu kilku eksperymentowanie, odkryłem, że poniższa zasada wyłącza również możliwość podążania za linkami w przeglądarkach webkit, oprócz powodowania wyłączania efektów estetycznych-patrz http://jsfiddle.net/3nkcdeao/
W związku z tym, będziesz musiał być nieco bardziej selektywny co do tego, jak modyfikujesz Zasady dla Przypadku Telefonu komórkowego niż to, co tutaj pokazuję, ale może to być pomocny punkt wyjścia: {]}

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

Jako przypis boczny, wyłączanie zdarzeń wskaźników na rodzicu, a następnie jawne włączanie ich na dziecku obecnie powoduje, że wszelkie efekty najechania na rodzica stają się ponownie aktywne, jeśli element potomny wejdzie :hover.
Zobacz http://jsfiddle.net/38Lookhp/5/

B. Jeśli wspierasz starsze renderery internetowe, będziesz musiał wykonać nieco więcej pracy, usuwając wszelkie reguły, które ustawiają specjalne style podczas :hover. Aby zaoszczędzić wszystkim czas, możesz po prostu zbudować automatyczne kopiowanie + sed ING polecenie, które uruchamiasz na standardowych arkuszach stylów, aby utworzyć telefon komórkowy wersje. To pozwoli Ci po prostu napisać / zaktualizować standardowy kod i usunąć wszelkie reguły stylu, które używają :hover dla mobilnej wersji Twoich stron.

  1. (i) alternatywnie, po prostu uświadom użytkownikom, że masz m.website.com dla urządzeń mobilnych oprócz twojego website.com . chociaż subdomaining jest najczęstszym sposobem, Możesz również mieć inną przewidywalną modyfikację danego adresu URL, aby umożliwić użytkownikom mobilnym dostęp do zmodyfikowanych stron. Na na tym etapie chciałbyś mieć pewność, że nie muszą modyfikować adresu URL za każdym razem, gdy przechodzą do innej części witryny.

Ponownie tutaj, możesz być w stanie po prostu dodać dodatkową regułę lub dwie do arkuszy stylów lub być zmuszony do zrobienia czegoś nieco bardziej skomplikowanego za pomocą sed lub podobnego narzędzia. Prawdopodobnie najłatwiej byłoby zastosować: nie do Twoich zasad stylizacji, takich jak div:not(.disruptive):hover {..., w których dodałbyś {[6] } do elementów robiących irytujące rzeczy dla użytkowników mobilnych korzystających z js lub język serwera, zamiast wymontowywać CSS.

  1. (II) możesz rzeczywiście połączyć dwa pierwsze i (jeśli podejrzewasz, że użytkownik wędrował do złej wersji strony) możesz zasugerować, aby przełączyć się na / z wyświetlacza typu mobilnego, lub po prostu mieć link, który pozwala użytkownikom flopować tam iz powrotem. Jak już wspomniano, @media queries może być również czymś, co należy wykorzystać do określenia, co jest używane do odwiedzania.

  2. (III) jeśli masz ochotę na jQuery rozwiązanie gdy już wiesz, które urządzenia są "dotykowe", a które nie, może się okazać, że CSS nie jest ignorowany na urządzeniach z Ekranem dotykowym pomocny.

 7
Author: SeldomNeedy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:46

Spróbuj tego:

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

UPDATE: niestety W3C usunęło tę właściwość ze specyfikacji ( https://github.com/w3c/csswg-drafts/commit/2078b46218f7462735bb0b5107c9a3e84fb4c4b1).

 5
Author: Marouen Mhiri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-01 12:42:58

Możesz użyć Modernizr JS( Zobacz także tę odpowiedź Stackkoverflow), lub stworzyć niestandardową funkcję 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');
} 

Aby wykryć obsługę zdarzenia touch w przeglądarce, a następnie przypisać zwykłą właściwość CSS, przechodząc przez element z klasą html.no-touch, Tak:

html.touch a {
    width: 480px;
}

/* FOR THE DESKTOP, SET THE HOVER STATE */
html.no-touch a:hover {
   width: auto;
   color:blue;
   border-color:green;
}
 4
Author: Giacomo Paita,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:09

Napotkałem ten sam problem (w moim przypadku z mobilnymi przeglądarkami Samsunga) i dlatego natknąłem się na to pytanie.

Dzięki odpowiedź Calsala znalazłem coś, co moim zdaniem wykluczy praktycznie wszystkie przeglądarki desktopowe, ponieważ wydaje się być rozpoznawane przez przeglądarki mobilne, które próbowałem (zobacz zrzut ekranu z skompilowanej tabeli: CSS pointer feature detection table ).

MDN web docs stwierdza, że

Wskaźnik CSS @ media funkcja może być używana do stosowania stylów opartych na czy podstawowym mechanizmem wejściowym użytkownika jest urządzenie wskazujące, oraz jeśli tak, to jak dokładne jest

.

Odkryłem, że pointer: coarse jest czymś, co jest nieznane wszystkim przeglądarkom stacjonarnym w załączonej tabeli, ale znane wszystkim przeglądarkom mobilnym w tej samej tabeli. Wydaje się to być najskuteczniejszym wyborem, ponieważ wszystkie inne wartości słowa kluczowego wskaźnika dają niespójne wyniki.

Stąd można zbuduj Zapytanie o media, takie jak Calsal opisane, ale nieco zmodyfikowane. Wykorzystuje odwróconą logikę, aby wykluczyć wszystkie urządzenia dotykowe.

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;
    }
}

Skompilowany CSS:

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

Jest to również opisane w tym gist stworzyłem po zbadaniu problemu. Codepen do badań empirycznych.

UPDATE : W chwili pisania tej aktualizacji, 2018-08-23, i wskazał @DmitriPavlutin ta technika nie wydaje się już działać Firefox desktop.

 3
Author: ProgrammerPer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-23 07:15:36

Jest to również możliwe obejście, ale będziesz musiał przejść przez swój css i dodać klasę .no-touch przed najechaniem na styl.

Javascript:

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

Przykład 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>

Źródło

P. S. ale pamiętajmy, że na rynku pojawia się coraz więcej urządzeń dotykowych, które jednocześnie obsługują wprowadzanie myszy.

 1
Author: mr.mii,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-05 17:55:38

To może nie jest jeszcze idealne rozwiązanie (i to z jQuery), ale może jest to kierunek / koncepcja do pracy: a co z robieniem tego na odwrót? Co oznacza domyślnie dezaktywację Stanów css: hover i aktywację ich, jeśli w dowolnym miejscu dokumentu zostanie wykryte Zdarzenie mousemove. Oczywiście to nie działa, jeśli ktoś wyłączył js. Co jeszcze może mówić przeciwko robieniu tego w ten sposób?

Może Tak:

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");
});
 1
Author: lars at upstruct,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-12 10:29:06

Pomogło mi: link

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");
                    }
                }
            }
        }
    }
}
 0
Author: mineroot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-06 14:53:28

Zgodnie z Jasons answer możemy adresować tylko urządzenia, które nie obsługują hover z czystymi zapytaniami css media. Możemy również zwracać się tylko do urządzeń, które obsługują hover, jak moogals answer w podobnym pytaniu, z @media not all and (hover: none). Wygląda dziwnie, ale działa.

Zrobiłem z tego Sass mixin dla łatwiejszego użycia:

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

Poniżej zmieni się kolor tła .container z czerwonego na niebieski po najechaniu na urządzenia, które go obsługują i pozostają czerwone dla dotyku urządzenia:

.container {
    background-color: red;

    @include hover-supported() {
        background-color: blue;
    }
}
 0
Author: Calsal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-22 14:23:04

Można to rozwiązać za pomocą sass / scss i zapytania o media z żądanym punktem przerwania.

.myclass {
    background-color: blue;
    &:hover {
        @media screen and (max-width: 320px) {
            background-color: red;
        }
    }
}
 -1
Author: albydarned,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-18 20:49:57