Подтвердить что ты не робот

Медиа-запрос для устройств, поддерживающих зависание

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

Я прочитал в функцию Interaction Media Queries, и похоже, что это должно сделать трюк. Я бы мог сделать что-то вроде:

@media (hover: none) {
  /* behaviour for touch browsers */
}

В соответствии с CanIUse он доступен во всех браузерах, которые мне нужны для поддержки, кроме IE11 и Firefox.

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

@media not (hover: none) {
  /* behaviour for desktop browsers */
}

Однако это не работает вообще.

Пример псевдокода того, что я пытаюсь сделать:

.myelement {
  /* some styling */
  /* note: no hover state here */
}
@media(this device supports hover) {
  .myelement:hover {
    /* more styling */
  }
}

Итак, есть ли способ сделать эту работу таким образом, или я ошибаюсь?

4b9b3361

Ответ 1

Благодаря комментариям Dekel я решил это, выполнив логику в JS и вместо этого применив класс:

например.

const canHover = !(matchMedia('(hover: none)').matches);
if(canHover) {
  document.body.classList.add('can-hover');
}

Затем в таблице стилей:

.myElement {
  background: blue;
}
.can-hover .myElement:hover {
  background: red;
}

Я тестировал это на настольных компьютерах Chrome, Safari и Firefox, а также на iOS Safari и работает как ожидалось.

Ответ 2

not должен префикс типа носителя (экран, печать, все и т.д.), а не средство массовой информации (наведение, точка и т.д.).

Неправильно:

@media not (hover: none)

Правильно:

@media not all and (hover: none)

Да, его неинтуитивный и странный. Источник (см. комментарии).

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

Ответ 3

Из спецификаций:

none

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

     

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

Если ваш браузер (мобильный/сенсорный) поддерживает длительное нажатие для имитации наведения, использование hover: none не будет работать. Вы можете просто использовать значение по умолчанию и переопределить его (с приоритетом по умолчанию css):

body {
    background: red;
}

@media (hover: hover) {
  body {
    background: blue;
  }
}

Рабочий стол будет иметь фон blue, а для мобильного /touch будет red фон

Проверьте следующий пример:
https://jsfiddle.net/mcy60pvt/1/

Чтобы проверить возможность длительного нажатия на мобильник, вы можете использовать этот пример:
https://jsfiddle.net/mcy60pvt/3/

В приведенном выше примере зеленый блок имеет определение :hover для рабочего стола и мобильного устройства, однако для рабочего стола фон будет меняться на yellow, а для мобильных устройств (с длинным нажатием) он изменится на white.

Вот пример css для последнего примера:

body {
    background: red;
}
div.do-hover {
  border: 1px solid black;
  width: 250px;
  height: 250px;
  background: green;
}
div.do-hover:hover {
  background: white;
}

@media (hover: hover) {
  body {
    background: blue;
  }
  div.do-hover:hover {
    background: yellow;
  }
}

В этом примере - браузеры, которые не поддерживают :hover, будут просматривать окно hover me с зеленым фоном, а во время "наведения" (касание/длительное нажатие) - фон изменится на белый.

Обновление

Что касается добавленного псевдокода:

.myelement {
    /* some styling #1 */
    /* note: no hover state here */
}
@media(hover: hover) {
    .myelement {
        /* some styling that override #1 styling in case this browser suppot the hover*/
    }
    .myelement:hover {
        /* what to do when hover */
    }
}

Ответ 4

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

Я сделал из него смесь Sass для упрощения использования:

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

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

.container {
    background-color: red;

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

Ответ 5

Для поддержки Firefox (см. Https://bugzilla.mozilla.org/show_bug.cgi?id=1035774) вам необходимо дважды написать некоторые правила. Обратите внимание, хотя в вопросе я не указал pointer: coarse если предположить, что целью этих правил является нацеливание на мобильные экраны:

/* BEGIN devices that DON'T pinch/zoom */
/* If https://bugzilla.mozilla.org/show_bug.cgi?id=1035774 
is fixed then we can wrap this section in a ...
@media not all and (pointer: coarse) and (hover: none) {
.. and do away with the 'NEGATE' items below */

.myelement {
  /* some styling that you want to be desktop only (style as an anchor on desktop) */
  font-size: 14px;
  text-decoration: underline;
  border: none;
}
/* END devices that DON'T pinch/zoom */

/* BEGIN devices that DO pinch/zoom */   
@media (pointer: coarse) and (hover: none) {
  .myelement {
    /* style as a large button on mobile */
    font-size: inherit;  /* maintain e.g. larger mobile font size */
    text-decoration: none;  /* NEGATE */
    border: 1px solid grey;
  }

  .myelement:hover {
    /* hover-only styling */
  }
}
/* END devices that DO pinch/zoom */

Комбинация (pointer: coarse) and (hover: none) должна стать более полезной для целевых мобильных устройств, так как мобильные экраны становятся больше, и мы теряем корреляцию между размерами в пикселях и между мобильным и настольным компьютерами (уже в том случае, когда вы хотите различать планшет и рабочий стол)

Ответ 6

Вы можете использовать этот миксин Sass для стилизации наведения, он будет использовать рекомендованную замену :active для сенсорных устройств. Работает во всех современных браузерах и IE11.

/**
 Hover styling for all devices and browsers
 */
@mixin hover() {
    @media (hover: none) {
        -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
        &:active {
            @content;
        }
    }

    @media (hover: hover), all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
        &:hover {
            @content;
        }
    }
}

.element {
    @include hover {
         background: red;
    }
}