Почему этот PNG не работает для фонового изображения CSS, когда он используется в другом месте в качестве маски, но после загрузки в Imgur он работает?

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

Единственная разница между ними заключается в том, что последний («Imgur») был загружен в Imgur и, похоже, повторно сохранен.

Оригинал

Имгур

.mask {
  background-color: navy;
  -webkit-mask-size: 144px;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: 0 0;
  mask-size: 144px;
  mask-repeat: no-repeat;
  mask-position: 0 0;
}
 #orig .mask {
  -webkit-mask-image: url("https://i.stack.imgur.com/ebAGH.png");
  mask-image: url("https://i.stack.imgur.com/ebAGH.png");
}
 #orig .bg {
  background-image: url("https://i.stack.imgur.com/ebAGH.png");
}
 #imgur .mask {
  -webkit-mask-image: url("https://i.imgur.com/DrErTaH.png");
  mask-image: url("https://i.imgur.com/DrErTaH.png");
}
 #imgur .bg {
 background-image: url("https://i.imgur.com/DrErTaH.png");
}
/* just fluff below */
body {
  background-color: #a0a0a0;
  background-image: linear-gradient(45deg, #808080 25%, transparent 25%), linear-gradient(-45deg, #808080 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #808080 75%), linear-gradient(-45deg, transparent 75%, #808080 75%);
  background-size: 20px 20px;
  background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
}
p {
  background-color: white;
  padding: 5px;
}
.mask, .bg, img {
  border: 1px solid black;
  display: inline-block;
  width: 144px;
  height: 144px;
}
<div id = "orig">
  <p>Orignal</p>
  <div class = "mask"></div>
  <div class = "bg"></div>
  <img src = "https://i.stack.imgur.com/ebAGH.png">
</div>
<div id = "imgur">
  <p>Imgur</p>
  <div class = "mask"></div>
  <div class = "bg"></div>
  <img src = "https://i.imgur.com/DrErTaH.png">
</div>

Почему верхнее исходное изображение не работает в качестве фона?

Кроме того, если я закомментирую часть маскировки, фон снова заработает? Я так потерян...

Обновлено: в Firefox кажется, что фоновое изображение работает, но оно по-прежнему не работает как маска.

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

Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
2
0
133
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вероятно, это может быть разрешение экрана оригинала, установленное как 2,834 пикселя / мм, поскольку это не веб-стандарт, но я добавил для вас обходной путь, инкапсулировав его в функцию image() css, которая перекодирует его для отображения, вы не получит «замаскированную» часть, но вы можете использовать маску в качестве маски.

.mask {
  background-color: navy;
  -webkit-mask-size: 144px;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: 0 0;
  mask-size: 144px;
  mask-repeat: no-repeat;
  mask-position: 0 0;
}
 #orig .mask {
  -webkit-mask-image: image(url("https://i.stack.imgur.com/ebAGH.png"));
  mask-image: image(url("https://i.stack.imgur.com/ebAGH.png"));
  
}
 #orig .bg {
  background-image: url("https://i.stack.imgur.com/ebAGH.png");
}
 #imgur .mask {
  -webkit-mask-image: url("https://i.imgur.com/DrErTaH.png");
  mask-image: url("https://i.imgur.com/DrErTaH.png");*/
}
 #imgur .bg {
 background-image: url("https://i.imgur.com/DrErTaH.png");
}
/* just fluff below */
body {
  background-color: #a0a0a0;
  background-image: linear-gradient(45deg, #808080 25%, transparent 25%), linear-gradient(-45deg, #808080 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #808080 75%), linear-gradient(-45deg, transparent 75%, #808080 75%);
  background-size: 20px 20px;
  background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
}
p {
  background-color: white;
  padding: 5px;
}
.mask, .bg, img {
  border: 1px solid black;
  display: inline-block;
  width: 144px;
  height: 144px;
}
<div id = "orig">
  <p>Orignal</p>
  <div class = "mask"></div>
  <div class = "bg"></div>
  <img src = "https://i.stack.imgur.com/ebAGH.png">
</div>
<div id = "imgur">
  <p>Imgur</p>
  <div class = "mask"></div>
  <div class = "bg"></div>
  <img src = "https://i.imgur.com/DrErTaH.png">
</div>

Спасибо за ответ, но я не думаю, что разрешение печати повлияет на это. Также не объясняет, почему из-за маскировки фон не работает. Интересный трюк с функцией изображения.

Sarke 08.10.2022 15:55

И это действительно тот же размер печати, только в метрической системе.

Sarke 08.10.2022 15:57
Ответ принят как подходящий

Это связано с тем, что по спецификациям ресурс <image>, используемый для mask-image, извлекается с помощью cross-origin: anonymous:

<mask-source>s и <clip-source>s предъявляют особые требования к извлечению ресурсов.

Пользовательские агенты должны использовать потенциально поддерживающий CORS метод выборки, определенный спецификацией [FETCH] для всех значений <mask-source>, <clip-source> и <image> в свойствах mask-image, mask-border-source и clip-path. При извлечении пользовательские агенты должны использовать «анонимный» режим, установить источник перехода на URL-адрес таблицы стилей и установить источник на URL-адрес содержащего документа. Если это приводит к сетевым ошибкам, эффект будет таким же, как если бы было указано значение none.

Поддомен https://i.stack.imgur.com не передает правильный Access-Control-Allow-Origin: * HTTP-заголовок, поэтому запрос блокируется.
С другой стороны, https://i.imgur.com/ отправляет правильные заголовки, поэтому мы можем безопасно загрузить изображение:

https://i.stack.imgur.com/ebAGH.png: <img src = "https://i.stack.imgur.com/ebAGH.png" crossorigin = "anonymous"><br>
https://i.imgur.com/DrErTaH.png: <img src = "https://i.imgur.com/DrErTaH.png" crossorigin = "anonymous">

(Обратите внимание, что существует этот метазапрос для изменения поведения субдомена StackOverflow).


Согласно BUG 786507 на самом деле здесь не было выявлено какой-либо угрозы, но это следует из текущей передовой практики «полной защиты изображений с помощью CORS».
Так вот как это.


Что касается того, почему это иногда не работает в вашем Chrome как background-image, я не совсем уверен и не могу воспроизвести на своей стороне, но я подозреваю, что это какая-то проблема с кэшированием, когда они используют запрос cross-origin: anonymous вместо запроса по умолчанию. . Вы можете открыть вопрос на https://crbug.com после того, как проверите панель «Сеть» в своих инструментах разработки.

Ну, конечно, это должен был быть гребаный CORS... Спасибо за информацию, я не знал, что у некоторых изображений есть требование CORS. У нашего сервера и CDN та же проблема, что и у SO и их i.stack.imgur.com.

Sarke 12.10.2022 01:55

@Sarke Должен признаться, я тоже нахожу это немного странным, они здесь используют кросс-происхождение. Маскировка ничего не должна выставлять напоказ. В основном мы можем делать то, что он делает в <canvas>, без каких-либо проблем с CORS. И я не думаю, что есть какие-либо планы по добавлению обратных отзывов из Paint API, так что... Возможно, SVG <mask> был первоначальной причиной, и они просто распространили его повсюду, я не знаю.

Kaiido 12.10.2022 01:59

По-видимому, у холста drawImage() тоже есть эта проблема: developer.mozilla.org/en-US/docs/Web/HTTP/…

Sarke 12.10.2022 02:04
drawImage будет «испортить» холст, это означает, что нельзя будет прочитать данные пикселя обратно, но он все еще сможет отображать изображение и даже использоваться в качестве маски. Я выкопал эту ошибку из истории, и, похоже, никогда не было реальной выявленной угрозы, просто «лучшая практика» в будущем.
Kaiido 12.10.2022 02:08

Скорее всего, такое поведение в Chrome вызвано ошибкой (безопасности?), которая, в свою очередь, кажется, вызвана агрессивной (странной?) оптимизацией. DevTools->Network может дать некоторое представление об этом, во-первых, мы можем наблюдать там, что ресурс для mask-image извлекается с помощью sec-fetch-mode: cors.
Оптимизация становится очевидной, если мы изменим порядок элементов так, что background-image начнет работать и в Chrome, более того, mask-image тоже заработает, даже если в Firefox не работает, например:

.mask {
  background-color: navy;
  -webkit-mask-size: 144px;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: 0 0;
  mask-size: 144px;
  mask-repeat: no-repeat;
  mask-position: 0 0;
}
 #orig .mask {
  -webkit-mask-image: url("https://i.stack.imgur.com/ebAGH.png");
  mask-image: url("https://i.stack.imgur.com/ebAGH.png");
}
 #orig .bg {
  background-image: url("https://i.stack.imgur.com/ebAGH.png");
}
 #imgur .mask {
  -webkit-mask-image: url("https://i.imgur.com/DrErTaH.png");
  mask-image: url("https://i.imgur.com/DrErTaH.png");
}
 #imgur .bg {
 background-image: url("https://i.imgur.com/DrErTaH.png");
}
/* just fluff below */
body {
  background-color: #a0a0a0;
  background-image: linear-gradient(45deg, #808080 25%, transparent 25%), linear-gradient(-45deg, #808080 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #808080 75%), linear-gradient(-45deg, transparent 75%, #808080 75%);
  background-size: 20px 20px;
  background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
}
p {
  background-color: white;
  padding: 5px;
}
.mask, .bg, img {
  border: 1px solid black;
  display: inline-block;
  width: 144px;
  height: 144px;
}
<div id = "orig">
  <p>Orignal</p>
  <div class = "bg"></div>
  <div class = "mask"></div>
  <img src = "https://i.stack.imgur.com/ebAGH.png">
</div>

В данном случае, в Chrome DevTools->Network, проверив Disable cache , мы можем наблюдать только один сетевой запрос, с sec-fetch-mode: no-cors, для всех background-image, mask-image и img.src, скорее всего срабатывающий по правилу background-image, а их три запросы в Firefox. Таким образом, мы можем заключить, что Chrome все равно хранит кэш в памяти, но это кэширование, похоже, реализуется путем сопоставления URL , а не Request , поскольку он игнорирует Request.mode.
Учитывая это, можно сделать вывод, что он не работает в исходном порядке элементов, потому что Chrome использует для background-image кешированный результат неудачного запроса для mask-image путем сопоставления кеша по тому же URL.

Другие вопросы по теме