CSS фильтр: инвертирование не работает с фоновым цветом - PullRequest
1 голос
/ 16 апреля 2020

У меня есть следующее CSS, примененное к тегу <html>: filter: invert(1);

Все элементы инвертируются даже background-color элементов, (Chrome v80)

После того, как я попробую то же самое в Safari iOS 13 / Safari MacOS, каждый элемент будет инвертирован, за исключением background-color *1009*

CSS, свойство фильтра поддерживается для всех браузеров, которые я запускаю:

https://caniuse.com/#feat = mdn-css_properties_filter .

Может ли кто-нибудь объяснить это поведение?

html {
  filter: invert(1);
  /* this background-color does not change on ios+other browsers */
  background: #fff;
  padding: 50px;
}

body {
  background-color: #0000ff;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

.text {
  text-align: center;
  color: red;
}
<div class="text">
  If it works: color should not be red, background should not be blue
</div>

1 Ответ

1 голос
/ 17 апреля 2020

TL; DR : не слишком связывайтесь с элементом html.

Простой обходной путь - заблокировать фоновое распространение body на холсте документа, но сделайте так, чтобы он принял тот же размер, что и html, удалив его поле и применив все стили, которые были на html к телу, и те стили, которые были у вас на body, к оболочке <div>.

html {
  /* block body's background propagation */
  background: #FFF;
}


/* move all one layer down */
body {
  filter: invert(1);
  background: #fff;
  padding: 50px;
  /* make it cover the full canvas */
  margin: 0;
}
.wrapper {
  background-color: #0000ff;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

.text {
  text-align: center;
  color: red;
}
<div class="wrapper">
  <div class="text">
    If it works: color should not be red, background should not be blue and border should not be white
  </div>
</div>

Более подробные наблюдения:

Здесь есть несколько концепций, и их взаимодействие не так просто asp (по крайней мере для меня ...).

  • «Слои рендеринга»: при рисовании страницы обычно будет несколько слоев рендеринга, возможно, вложенных, на которые будут влиять такие эффекты, как фильтры или непрозрачность. применяться Спецификации определяют только «контексты стекирования», для нашего случая здесь они совпадают.
  • «Холст документа» : у каждого документа есть фоновый холст, которого нет в DOM и который выступает в качестве самого глубокого «слоя рендеринга».
  • «Фоновое распространение» : Некоторые специальные элементы имеют особые поведения в отношении их свойства CSS background. Примечательно, что html и body могут дать свой собственный фон "холсту документа". Основной рабочий процесс c равен

    • , если фон html не none и не transparent, используйте его для «холста документа».
    • , если еще Фон body не none и не transparent, используйте его для «холста документа».
    • иначе делайте что хотите (обычно браузеры отображают белый solid цвет).
  • Эффекты «постобработки», такие как filter и opacity, должны применяться ко всему «слою рендеринга», когда весь его внутренний контент уже визуализирован.

  • Установка таких эффектов «постобработки» на элемент должна изолировать этот элемент и создать из него новый «слой рендеринга».

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

Что точно, так это что у нас есть проблемы [Compat] ...

Мало того, что не все браузеры следуют одним и тем же правилам, но некоторые браузеры будут вести себя по-разному, когда страница представлена ​​в виде отдельного окна или в iframe.

Так как результаты теста действительно различаются для оконной и рамочной визуализации, и что StackSnippet разрешает только рамочную визуализацию, я вынужден передать тестовый пример на аутсорсинг в this plnkr .

html {
  background: red;
  height: 50vh;
  border: 10px solid green;
}

.opacity {
  opacity: 0.5;
}

.filter {
  filter: invert(1);
}

body {
  background: yellow;
  margin: 10vh;
  border: 2px solid green;
}

Результаты этих тестов для основных браузеров:

При работе в окне : (порядок скриншотов слева направо: ничего фильтр * 108 5 *, opacity , filter + opacity ).

  • Firefox не применяет ни фильтр, ни непрозрачность к холсту документа. Firefox screenshots
  • Край не применяет ни фильтр, ни непрозрачность к холсту документа. (аналогично Firefox)
  • Chrome <81 не применяет ни фильтр, ни непрозрачность к холсту документа. (аналогично Firefox) </li>
  • Chrome> = 81 применяет фильтр и непрозрачность к холсту документа.
    Chrome screenshots
  • Safari делает
    • применять фильтр равномерно, когда не установлена ​​прозрачность.
    • не применять прозрачность на холсте документа
    • создать новый слой для <html>, когда установлена ​​и применяется прозрачность и непрозрачность, и фильтр на фоне <html>.
      Однако теперь он использует цвет фона <body> в качестве холста документа ... но не влияет на фильтр.
    Safari screenshots

В кадре : (порядок скриншотов слева направо: ничего , фильтр , непрозрачность , фильтр + непрозрачность ).

  • Firefox не применяет ни фильтр, ни непрозрачность к холсту документа.
    Firefox screenshots
  • Край не применяет ни фильтр, ни непрозрачность к холсту документа. (аналогично Firefox)
  • Chrome (все версии) не применяет ни фильтр, ни непрозрачность к холсту документа.
    Chrome screenshots
  • Safari
    • применяет фильтр равномерно, когда не установлена ​​прозрачность.
    • устанавливает холст документа прозрачным, когда установлена ​​прозрачность, и создает новый слой для <html>, к которому применяется непрозрачность.
    • создайте новый слой для <html>, когда установлена ​​непрозрачность, и примените прозрачность и фильтр к фону <html>.
      Однако теперь он устанавливает прозрачность холста документа.
    Safari screenshots

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


Постскриптум:

  • Вот проблема Chromium , из которой было введено новое поведение Chrome.
  • Вот предложение для Авторы веб-страниц могут определить фон холста документа как прозрачный для некоторых устройств.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...