Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG LinearGradient hidden if svg is hidden in seperate class

Tags:

html

css

svg

Basically what Is happening is the linearGradient fill is hidden if the svg is hidden in a parallell element

.mobile {
  display: none;
}

.content-svg {
  border: 1px solid black;
}
<div class="desktop">
  <!-- stuff here -->
</div>

<div class="mobile">
  <svg class="mobile-svg" height="150" width="400">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
  Sorry, your browser does not support inline SVG.
  </svg>
</div>

<div class="content">
  <svg class="content-svg" height="150" width="400">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
  Sorry, your browser does not support inline SVG.
  </svg>
</div>

as you can see in the snippet above, the SVG element is there, the linearGradient fill is hidden

If I change the fill to a solid colour set in my CSS it works as expected, this only seems to happen with gradient fills

now this is just a basic example of my overall issue, I want to avoid recreating the SVG since I am using this in Vue and have created a reusable svg component

like image 902
Smokey Dawson Avatar asked Oct 19 '25 14:10

Smokey Dawson


1 Answers

Either consider a different ID for the gradients:

.mobile {
  display: none;
}

.content-svg {
  border: 1px solid black;
}
<div class="desktop">
  <!-- stuff here -->
</div>

<div class="mobile">
  <svg class="mobile-svg" height="150" width="400">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
  Sorry, your browser does not support inline SVG.
  </svg>
</div>

<div class="content">
  <svg class="content-svg" height="150" width="400">
  <defs>
    <linearGradient id="grad2" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad2)" />
  Sorry, your browser does not support inline SVG.
  </svg>
</div>

Or consider only one gradient if it's the same used in both SVG (related: Gradients hidden using SVG symbols)

.mobile {
  display: none;
}

.content-svg {
  border: 1px solid black;
}
<div class="desktop">
  <!-- stuff here -->
</div>

  <svg  height="0" width="0">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  </svg>
<div class="mobile">
  <svg class="mobile-svg" height="150" width="400">
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
  Sorry, your browser does not support inline SVG.
  </svg>
</div>

<div class="content">
  <svg class="content-svg" height="150" width="400">
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
  Sorry, your browser does not support inline SVG.
  </svg>
</div>

Repeating the same ID is invalid and only the first one will be considered for both gradients and since the first one has display:none it will not render.

Changing the order will make your code work because the first one will no more have display:none

.mobile {
  display: none;
}

.content-svg {
  border: 1px solid black;
}
<div class="desktop">
  <!-- stuff here -->
</div>
<div class="content">
  <svg class="content-svg" height="150" width="400">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
  Sorry, your browser does not support inline SVG.
  </svg>
</div>
<div class="mobile">
  <svg class="mobile-svg" height="150" width="400">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
  Sorry, your browser does not support inline SVG.
  </svg>
</div>
like image 168
Temani Afif Avatar answered Oct 21 '25 02:10

Temani Afif