0

I need to add a very thin stripes pattern over an image in html. I can't really add it to the image itself for multiple reasons (images are uploaded in a CMS, must be used in other places without the stripes, and i also want the pattern to remain unscaled, whereas the images do scale...).

So i made a transparent PNG with the pattern, put it over the image with a pseudo element and use background-repeat to loop it over the entire image (see snippet).

The problem i have is that the image is blinking/flashing when i scroll the page down. Tested on Firefox & Chrome with the same result. I tried different other options like using a very big stripe image to avoid background-repeat, or using a non transparent image with mix-blend-mode:multiply, but the result is always the same.

I also tried a pure css solution with repeating linear background but the rendering is not very good because the pattern is too thin.

The only way i can have a clean rendering is by inlaying the pattern in the original image, no blinking then, but this is not really an option for the reasons mentionned above.

Any ideas ? Thanks :-)

#container {
  position: relative;
}

#container:after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: url(https://indelebil.fr/stripes.png) repeat;
}

img {
  display: block;
  max-width: 100%;
}
<div id="container">
  <img src="https://indelebil.fr/sample.jpg" />
</div>
eric.rondo
  • 43
  • 5
  • 1
    In my opinion this is not issue with CSS but monitor and rendering engine in browser itself. Lines are to thin (1px) to be displayed correctly (always the same) at every state while scrolling. Proof - zoom page to 110% or 120% - lines will look weird because then cannot fit into pixels, display has to mimic it somehow. Then zoom to 150% - works fine. It would be okay with straight lines but yours are rotated 45degrees and it just has to fail. – chojnicki May 11 '20 at 14:41
  • You are probably right, this is a "subpixel" issue, but if the pattern is printed directly on the image (rasterized), the flashing effect doesn't occur, that is why i am wondering is there is another way of doing this that the rendering engine would handle better... – eric.rondo May 11 '20 at 17:00

2 Answers2

0

We can do this with linear-gradient

No need to use strips.png

body {
    height: 300vh;
}

#container {
    position: relative;
    overflow: hidden;
}

#container:after {
    content: '';
    position: absolute;
    top: -200vh;
    left: 0;
    right: 0;
    bottom: 0;
    width: 200vw;
    height: 400vh;
    background-size: 3px 44px;
    background-repeat: repeat;
    background-image: linear-gradient(to left, transparent -5px, #000000a3 8px, transparent 26px, transparent);
    transform: rotate(-45deg) scale(1.5);
}

img {
    display: block;
    max-width: 100%;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Stack Overflow</title>
    <link rel="stylesheet" href="./styles.css">
</head>
<body>
<div id="container">
    <img src="https://indelebil.fr/sample.jpg" />
</div>
</body>
</html>
  • Thanks, yes, but this is is not the rendering we want, we use much thiner lines... but they dont render good with pure css :-/ – eric.rondo May 11 '20 at 16:58
0

I finally found a workaround, the flashing effect tends to disappear by lowering the pattern opacity, it is still present but it becomes kinda acceptable under 0.6% alpha.

By the way if anyone has a better way keeping 100% opacity i would be happy to hear about it !

#container {
  position: relative;
}

#container:after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: url(https://indelebil.fr/stripes.png) repeat;
  opacity:.5;
}

img {
  display: block;
  max-width: 100%;
}
<div id="container">
  <img src="https://indelebil.fr/sample.jpg" />
</div>
eric.rondo
  • 43
  • 5