Home > OS >  SVG Pattern with Gradient and Smooth Tile Transitions
SVG Pattern with Gradient and Smooth Tile Transitions

Time:02-24

I’m trying to understand how to apply an SVG pattern with a gradient that starts near the top of a web page and extends to the bottom.

I haven’t been able to apply the gradient to the entire pattern, only to the individual tiles that make up the pattern. I’ve tried applying the gradient to the tiles, to the pattern, to a element, and to a CSS background image.

Also, when the pattern is tiled, the rounded corners should only appear for the top tile, as the tiles overlap. For some reason the transparency is piercing from the overlapping tile all the way through to the background, even though the tile underneath has a fill color.

a. Is there any way to apply a gradient to the entire pattern, perhaps by wrapping it in another SVG?

b. How do I get rid of the display of rounded corners between the overlapping tiles, except for the top tile, which does not overlap another tile? Can the z-index of the tiles or the tile stacking order be changed?

I also tried creating a very long column of tiles in illustrator, which solves the problem of displaying the rounded corners between overlapping tiles and allows for applying a gradient to the entire pattern. The long SVG solution had several other issues:

c. Apparently if I’m using CSS parallax on a webpage, it’s impossible to hide the overflow and preserve3D, so the entire column has to be displayed.

d. The gradient is applied to the entire column, not just the pattern as rendered on the page, so most of the gradient is out of view most of the time.

e. Several of the tiles have single pixel lines of transparency separating them, even though they were all snapped in Illustrator. Apparently creating an SVG tile pattern in Illustrator will require manually entering the coordinates so that at least 1 pixel overlaps for each tile.

Any suggestions on how to create a pattern with a gradient that extends from near the top of a page all the way to the bottom with no transparent artifacts between the tiles would be welcome. Here’s an image of an SVG pattern test, and the codepen.

Thanks for your help!

https://codepen.io/ripmurdock/pen/JjOLXqL?editors=1000

SVG pattern with gradient

* {
  margin:0;
  padding:0;
}

body{
  background-color:tomato;
}

.gradient-1{
  color: white;
}
<svg width="100%" height="99.5vh">
 <defs>
   <pattern id="cc_vert_tiles-1" x="" y="" width="300" height="176" patternUnits="userSpaceOnUse" fill="url(#SVGID_1_)">
     <use href="#cp_3_ring_rnd4_uneq_1_" />
   </pattern>  
   
 <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="100.0005" y1="200" x2="100.0005" y2="4.882813e-004">
    <stop  offset="0.0443" style="stop-color:#FFFF00"/>
    <stop  offset="0.1669" style="stop-color:#FFFD00"/>
    <stop  offset="0.2387" style="stop-color:#FFF400"/>
    <stop  offset="0.2975" style="stop-color:#FFE600"/>
    <stop  offset="0.3491" style="stop-color:#FFD200"/>
    <stop  offset="0.3961" style="stop-color:#FFB800"/>
    <stop  offset="0.4392" style="stop-color:#FF9900"/>
    <stop  offset="0.468" style="stop-color:#FF7F00"/>
    <stop  offset="0.5948" style="stop-color:#BC7F00"/>
    <stop  offset="0.7949" style="stop-color:#587F00"/>
    <stop  offset="0.9343" style="stop-color:#197F00"/>
    <stop  offset="1" style="stop-color:#007F00"/>
</linearGradient>
   <path id="cp_3_ring_rnd4_uneq_1_" height="200" width="200" d="M200,190c0,5.522-4.478,10-10,10H10c-5.523,0-10-4.478-10-10V10C0,4.477,4.477,0,10,0h180
    c5.522,0,10,4.477,10,10V190z M5,99.621c0,52.467,42.533,95,95,95c52.467,0,95-42.533,95-95c0-52.467-42.533-95-95-95
    C47.533,4.621,5,47.154,5,99.621z"/>
 </defs>
 <g >
 <rect id="cc_vert_pat-1" width="200" height="110vh" fill="url(#cc_vert_tiles-1)" />
   </g>
</svg>

CodePudding user response:

a. Is there any way to apply a gradient to the entire pattern, perhaps by wrapping it in another SVG?

Every copy of a pattern tile will be identical. If you need a gradient to cover the whole document, then it would need to be a separate element.

b. How do I get rid of the display of rounded corners between the overlapping tiles, except for the top tile, which does not overlap another tile? Can the z-index of the tiles or the tile stacking order be changed?

The tiles in a pattern never overlap each other. Your pattern tiles are specified to be 300x176. Anything outside that region will not be rendered. However the path that you are using in your tile is 200x200. So 24 units of the bottom of the path are being clipped off (200-176). That is the reason why the bottom rounded corners are not showing.

If you want the whole of the path to be visible, then it needs to be no bigger than 300x176.

If you need your tiles to actually overlap, then patterns are not useful to you. You would need to draw all the tiles yourself. As per your Illustrator experiment you mentioned.

In the following example, I've changed the pattern dimensions to match the area that the path covers (200x200).

* {
  margin:0;
  padding:0;
}

body{
  background-color:tomato;
}

.gradient-1{
  color: white;
}
<svg width="100%" height="99.5vh">
 <defs>
   <pattern id="cc_vert_tiles-1" x="" y="" width="200" height="200" patternUnits="userSpaceOnUse" fill="url(#SVGID_1_)">
     <use href="#cp_3_ring_rnd4_uneq_1_" />
   </pattern>  
   
 <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="100.0005" y1="200" x2="100.0005" y2="4.882813e-004">
    <stop  offset="0.0443" style="stop-color:#FFFF00"/>
    <stop  offset="0.1669" style="stop-color:#FFFD00"/>
    <stop  offset="0.2387" style="stop-color:#FFF400"/>
    <stop  offset="0.2975" style="stop-color:#FFE600"/>
    <stop  offset="0.3491" style="stop-color:#FFD200"/>
    <stop  offset="0.3961" style="stop-color:#FFB800"/>
    <stop  offset="0.4392" style="stop-color:#FF9900"/>
    <stop  offset="0.468" style="stop-color:#FF7F00"/>
    <stop  offset="0.5948" style="stop-color:#BC7F00"/>
    <stop  offset="0.7949" style="stop-color:#587F00"/>
    <stop  offset="0.9343" style="stop-color:#197F00"/>
    <stop  offset="1" style="stop-color:#007F00"/>
</linearGradient>
   <path id="cp_3_ring_rnd4_uneq_1_" d="M200,190c0,5.522-4.478,10-10,10H10c-5.523,0-10-4.478-10-10V10C0,4.477,4.477,0,10,0h180
    c5.522,0,10,4.477,10,10V190z M5,99.621c0,52.467,42.533,95,95,95c52.467,0,95-42.533,95-95c0-52.467-42.533-95-95-95
    C47.533,4.621,5,47.154,5,99.621z"/>
 </defs>
 <g >
 <rect id="cc_vert_pat-1" width="200" height="110vh" fill="url(#cc_vert_tiles-1)" />
   </g>
</svg>

It is possible to have a gradient that covers all the tiles in the pattern. What you can do is apply the gradient to the rectangle, and turn the pattern into a mask.

* {
  margin:0;
  padding:0;
}

body{
  background-color:tomato;
}
<svg width="100%" height="99.5vh">
  <defs>
    <pattern id="cc_vert_tiles-1" x="" y="" width="200" height="200" patternUnits="userSpaceOnUse" fill="url(#SVGID_1_)">
      <use href="#cp_3_ring_rnd4_uneq_1_" fill="white" />
    </pattern>  
   
    <linearGradient id="SVGID_1_" gradientUnits="objectBoundingBox" x1="0" y1="1" x2="0" y2="0">
      <stop  offset="0.0443" style="stop-color:#FFFF00"/>
      <stop  offset="0.1669" style="stop-color:#FFFD00"/>
      <stop  offset="0.2387" style="stop-color:#FFF400"/>
      <stop  offset="0.2975" style="stop-color:#FFE600"/>
      <stop  offset="0.3491" style="stop-color:#FFD200"/>
      <stop  offset="0.3961" style="stop-color:#FFB800"/>
      <stop  offset="0.4392" style="stop-color:#FF9900"/>
      <stop  offset="0.468" style="stop-color:#FF7F00"/>
      <stop  offset="0.5948" style="stop-color:#BC7F00"/>
      <stop  offset="0.7949" style="stop-color:#587F00"/>
      <stop  offset="0.9343" style="stop-color:#197F00"/>
      <stop  offset="1" style="stop-color:#007F00"/>
    </linearGradient>
    
    <path id="cp_3_ring_rnd4_uneq_1_" d="M200,190c0,5.522-4.478,10-10,10H10c-5.523,0-10-4.478-10-10V10C0,4.477,4.477,0,10,0h180
      c5.522,0,10,4.477,10,10V190z M5,99.621c0,52.467,42.533,95,95,95c52.467,0,95-42.533,95-95c0-52.467-42.533-95-95-95
      C47.533,4.621,5,47.154,5,99.621z"/>
      
    <mask id="pat-mask">
      <rect id="cc_vert_pat-1" width="200" height="110vh" fill="url(#cc_vert_tiles-1)" />
    </mask>
  </defs>

  <g >
    <rect id="cc_vert_pat-1" width="200" height="110vh" fill="url(#SVGID_1_)" mask="url(#pat-mask)"/>
  </g>
</svg>

c. Apparently if I’m using CSS parallax on a webpage, it’s impossible to hide the overflow and preserve3D, so the entire column has to be displayed.

d. The gradient is applied to the entire column, not just the pattern as rendered on the page, so most of the gradient is out of view most of the time.

I'm not sure what you mean for these. You probably need to ask a separate question for these.

e. Several of the tiles have single pixel lines of transparency separating them, even though they were all snapped in Illustrator. Apparently creating an SVG tile pattern in Illustrator will require manually entering the coordinates so that at least 1 pixel overlaps for each tile.

This is normally due to antialiasing. It can be avoided by making sure that your tiles match screen pixel boundaries. If you do that, then you shouldn't need to overlap your tiles.

  • Related