Медиа-запрос, чтобы определить, является ли устройство сенсорным экраном

123

Как самый безопасный способ с помощью медиа-запросов сделать что-то, что происходит не на устройстве с сенсорным экраном? Если нет возможности, вы предлагаете использовать решение JavaScript, такое как !window.Touchили Modernizr?

JJJollyjim
источник
2
Перенесемся в 2018 год, CSS теперь изначально может делать это stackoverflow.com/a/50285058/1717735
Buzut

Ответы:

38

Я бы предложил использовать modernizr и использовать его функции медиа-запросов.

if (Modernizr.touch){
   // bind to touchstart, touchmove, etc and watch `event.streamId`
} else {
   // bind to normal click, mousemove, etc
}

Однако с использованием CSS есть псевдокласс, например, в Firefox. Вы можете использовать : -moz-system-metric (с сенсорным экраном) . Но эти функции доступны не для всех браузеров.

Для устройств Apple вы можете просто использовать:

if(window.TouchEvent) {
   //.....
}

Специально для Ipad:

if(window.Touch) {
    //....
}

Но они не работают на Android .

Modernizr предоставляет возможности обнаружения функций, и обнаружение функций - это хороший способ кодирования, а не кодирования на основе браузеров.

Стильные сенсорные элементы

Модернизатор добавляет классы в тег HTML именно для этой цели. В этом случае, touchи no-touchпоэтому вы можете стилизовать ваши прикосновения аспектов , связанных предваряя ваши селекторы с .touch. напр .touch .your-container. Кредиты: Бен Суинберн

Starx
источник
Правильно ли я считаю, что никакие псевдоклассы не работают со всеми современными устройствами / браузерами?
JJJollyjim 09
@ JJ56, да не все браузеры поддерживают сенсорные псевдоклассы. Но вот где modernizrбудет идеально :)
Starx 09
18
Modernizr.touchТест показывает только если поддерживает браузер потрогать события, которые не обязательно отражают сенсорный экран устройства. Например, телефоны Palm Pre / WebOS (сенсорные) не поддерживают события касания и поэтому не проходят этот тест.
numediaweb
5
Просто чтобы добавить к этому, если вы все равно включаете модернизатор; Модернизатор добавляет классы к тегу body именно для этой цели. В этом случае, touchи no-touchпоэтому вы можете стилизовать ваш сенсорные аспекты , связанные с предваряя ваши селекторы с .touch. Напр..touch .your-container
Бен Суинберн
2
Мне кажется, что modernizr добавляет класс касания к тегу html, а не к тегу body.
Робин Кокс
162

На самом деле в черновике медиа-запроса CSS4 есть свойство для этого .

Медиа-функция «указатель» используется для запроса информации о наличии и точности указывающего устройства, такого как мышь. Если устройство имеет несколько механизмов ввода, рекомендуется, чтобы UA сообщал характеристики наименее способного указывающего устройства из основных механизмов ввода. Этот медиа-запрос принимает следующие значения:

'none'
- механизм ввода устройства не включает указывающее устройство.

«грубый»
- механизм ввода устройства включает указательное устройство ограниченной точности.

«отлично»
- механизм ввода устройства включает точное указывающее устройство.

Это будет использоваться как таковое:

/* Make radio buttons and check boxes larger if we have an inaccurate pointing device */
@media (pointer:coarse) {
    input[type="checkbox"], input[type="radio"] {
        min-width:30px;
        min-height:40px;
        background:transparent;
    }
}

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

Совместимость браузера можно проверить в Quirksmode . Вот мои результаты (22 января 2013 г.):

  • Chrome / Win: работает
  • Chrome / iOS: не работает
  • Safari / iOS6: не работает
Znarkus
источник
3
Как это может быть ответ с наибольшим количеством баллов, если предоставленное решение не работает даже согласно плакату?
erdomester
5
Поддержка браузеров для этого уже не так плоха: Edge, Chrome, Safari, iOS и Android. См .: caniuse.com/#feat=css-media-interaction
Джоса,
3
Хороший ответ. Дополнительно: developer.mozilla.org/en-US/docs/Web/CSS/@media/hover
aross
У меня работает;) Спасибо за исследование!
Verri
53

По состоянию на середину 2013 года решения CSS не были широко доступны. Вместо...

  1. Николас Закас объясняет, что Modernizr применяет no-touchкласс CSS, когда браузер не поддерживает сенсорное управление.

  2. Или обнаружение в JavaScript с помощью простого фрагмента кода, позволяющего реализовать собственное решение, подобное Modernizr:

    <script>
        document.documentElement.className += 
        (("ontouchstart" in document.documentElement) ? ' touch' : ' no-touch');
    </script>

    Затем вы можете написать свой CSS как:

    .no-touch .myClass {
        ...
    }
    .touch .myClass {
        ...
    }
Саймон Ист
источник
Второй очень красивый. Для меня работает оберег! Спасибо.
Гаравани
@ bjb568 Спасибо за предложенное редактирование, которое является более современной альтернативой, но, поскольку оно работает только в IE 10 и выше, я думаю, что лучше пока оставить эту версию.
Саймон Ист
Похоже, этот класс будет в теге html; что тогда будет означать, что он отключен по умолчанию при использовании CSP.
Leo
36

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

http://www.w3.org/TR/css3-mediaqueries/

Таким образом, невозможно сделать это последовательно с помощью CSS или медиа-запросов, вам придется прибегнуть к JavaScript.

Нет необходимости использовать Modernizr, вы можете просто использовать простой JavaScript:

<script type="text/javascript">
    var is_touch_device = 'ontouchstart' in document.documentElement;
    if(is_touch_device) alert("touch is enabled!");
</script>
Алекс В
источник
AFAIK, window.touch&& window.TouchEventработают только на устройствах Apple.
Starx 09
22
@vsync Modernizr - отличный способ поместить все тесты, полезные для разработчиков, в поддерживаемую библиотеку, чтобы им не приходилось обращаться в Google каждый раз, когда им нужно тестировать определенную функцию, например, события касания и необходимость поиска этой страницы. К вашему сведению, существует специальная сборка Modernizr, которую вы можете настроить с помощью тестов, которые вам нужны. Это отличный способ всегда одинаково тестировать функции в разных проектах, независимо от того, используете ли вы синтаксис JS (например, Modernizr.touch) или классы CSS (.touch .my-element {}). Я думаю, что это оскорбление человеческого разума, когда мы не понимаем, что мы можем делать что-то, не изобретая каждый раз колесо заново.
Алехандро Гарсия Иглесиас
11
Ну, я работал над сотнями проектов, и мне это никогда не требовалось, в большинстве случаев все, что вам нужно, это очень небольшой набор тестов, я бы сказал, никогда не больше пяти (в большинстве случаев), так что просто найдите эти 5 и вставьте их в свой код напрямую, не нужно фактически заходить на веб-сайт Modernizer, создавать собственную сборку, включать ее на свою страницу или что-то еще. Разработчики не должны ТАК лениться. У веб-разработчика всегда должен быть образ мышления «как сделать код легче?» .. ИМХО и многолетний опыт. в настоящее время разработчикам нравится включать множество скриптов: /
vsync
2
Некоторые говорят, что это ленивый. Я говорю, зачем изобретать велосипед? Как насчет того, когда появится новое устройство / версия / платформа и ваш особый случай потребует изменения? Вы: а) Пытаетесь самостоятельно разработать код обнаружения особых случаев и выполнить бэкпорт на свой собственный код, повторно знакомясь с ним в процессе, или б) загружаете более свежую версию Modernizr и вставляете ее? Я знаю, что буду делать. +1 к GarciaWebDev.
Sc0ttyD
@ Sc0ttyD Я лично предпочитаю сначала научиться программировать, не полагаясь на библиотеки, такие как Modernizr. Когда-нибудь вам может понадобиться быть тем человеком, который занимается кодированием для нового устройства, и вы не хотите застревать, потому что вы не можете сделать это без библиотеки. Не говоря уже о том, что, вероятно, есть много людей, у которых просто нет времени на работе, чтобы изучить новую библиотеку.
Alex W
28

В 2017 году медиа-запрос CSS из второго ответа по-прежнему не работает в Firefox. Я нашел решение для этого: -moz-touch-enabled


Итак, вот кроссбраузерный медиа-запрос:

@media (-moz-touch-enabled: 1), (pointer:coarse) {
    .something {
        its: working;
    }
}
Соколове
источник
это должно быть выше и утвержденный ответ. firefox работает над реализацией спецификации, поэтому в -moz-touch-enabledближайшее время он не потребуется
Dogoku 04
может быть обновлено после 11 декабря. '18 wiki.mozilla.org/Release_Management/Calendar developer.mozilla.org/en-US/docs/Web/CSS/@media/…
retrovertigo
@ user3445853 OP спрашивает, как обнаружить (через медиа-запрос) устройство с сенсорным экраном. Если правило «(указатель: нет)» будет истинным, значит, у устройства точно нет сенсорного экрана. Но кто-то должен подтвердить мое мнение (или нет) :)
Sokołow
-moz-touch-enabledпредположительно не поддерживается в Firefox 58+. Как и в случае, это решение не распространяется на Firefox 58-63 (поскольку Firefox 64+ поддерживает запрос указателя). Источник: developer.mozilla.org/en-US/docs/Web/CSS/@media/…
fgblomqvist
24

Для этого есть медиа-запрос:

@media (hover: none) {  }

Помимо Firefox, он довольно хорошо поддерживается . Safari и Chrome - самые распространенные браузеры на мобильных устройствах, и этого может хватить до более широкого распространения.

Buzut
источник
2
... а также поддержка FF в ближайшие недели.
Retrovertigo
5

Это сработает. Если это не дает мне знать

@media (hover: none) and (pointer: coarse) {
    /* Touch screen device style goes here */
}

изменить: наведение по требованию больше не поддерживается

aleksa_95
источник
3

Это решение будет работать до тех пор, пока CSS4 не будет глобально поддерживаться всеми браузерами. Когда наступит этот день, просто используйте CSS4. но до тех пор это работает для текущих браузеров.

браузер-util.js

export const isMobile = {
  android: () => navigator.userAgent.match(/Android/i),
  blackberry: () => navigator.userAgent.match(/BlackBerry/i),
  ios: () => navigator.userAgent.match(/iPhone|iPad|iPod/i),
  opera: () => navigator.userAgent.match(/Opera Mini/i),
  windows: () => navigator.userAgent.match(/IEMobile/i),
  any: () => (isMobile.android() || isMobile.blackberry() || 
  isMobile.ios() || isMobile.opera() || isMobile.windows())
};

в процессе:

старый способ:

isMobile.any() ? document.getElementsByTagName("body")[0].className += 'is-touch' : null;

новый способ:

isMobile.any() ? document.body.classList.add('is-touch') : null;

Приведенный выше код добавит класс is-touch в тег body, если устройство имеет сенсорный экран. Теперь любое место в вашем веб-приложении, где у вас будет css для: hover, вы можете вызватьbody:not(.is-touch) the_rest_of_my_css:hover

например:

button:hover

будет выглядеть так:

body:not(.is-touch) button:hover

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

Патрик В. МакМахон
источник
0

добавление сенсорного экрана класса в тело с помощью JS или jQuery

  //allowing mobile only css
    var isMobile = ('ontouchstart' in document.documentElement && navigator.userAgent.match(/Mobi/));
    if(isMobile){
        jQuery("body").attr("class",'touchscreen');
    }
Matoeil
источник
0

Мне удалось решить эту проблему с помощью этого

@media (hover:none), (hover:on-demand) { 
Your class or ID{
attributes
}    
}
Робин Меди
источник
FYI, on-demandбыл удален из спецификации и из браузеров: github.com/w3c/csswg-drafts/commit/…
retrovertigo