Prevent SVG background bleed for icon?

白昼怎懂夜的黑 提交于 2019-12-24 11:59:34

问题


The goal is to prevent background bleed of SVG icons so they can appear as standalone files. Many answers to similar questions suggest putting a DIV or other container around the SVG element to prevent bleed, but the goal is to make the SVG icon stand alone without any dependency on a container.

Prepending a rect element to act as a background element doesn't work reliably as this method breaks for certain viewport aspect ratios.

Is this possible?

Note: to see the flaw, you must download and open the SVG file in the browser. Using JSFiddle/CodePen hides the problem because those sites encapsulate the SVG in a container (which fixes the bleed issue).

Download SVG here: https://gofile.io/?c=eKzjk7

Example SVG:

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 24 24" fill="rgb(255, 120, 50)" style="background-color: rgb(255, 255, 102); border-radius: 0%">
    
    <path d="M8 11.5c0-.83-.67-1.5-1.5-1.5S5 10.67 5 11.5 5.67 13 6.5 13 8 12.33 8 11.5zm7-5c0-.83-.67-1.5-1.5-1.5h-3C9.67 5 9 5.67 9 6.5S9.67 8 10.5 8h3c.83 0 1.5-.67 1.5-1.5zM8.5 15c-.83 0-1.5.67-1.5 1.5S7.67 18 8.5 18s1.5-.67 1.5-1.5S9.33 15 8.5 15zM12 1C5.93 1 1 5.93 1 12s4.93 11 11 11 11-4.93 11-11S18.07 1 12 1zm0 20c-4.96 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9zm5.5-11c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm-2 5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z"/>
    
    </svg>

Ideal output:

Actual output:


回答1:


Use a gradient and disable the repeat to avoid this:

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 24 24" fill="rgb(255, 120, 50)" style="background:linear-gradient(rgb(255, 255, 102),rgb(255, 255, 102)) no-repeat ; border-radius: 0%">
    
    <path d="M8 11.5c0-.83-.67-1.5-1.5-1.5S5 10.67 5 11.5 5.67 13 6.5 13 8 12.33 8 11.5zm7-5c0-.83-.67-1.5-1.5-1.5h-3C9.67 5 9 5.67 9 6.5S9.67 8 10.5 8h3c.83 0 1.5-.67 1.5-1.5zM8.5 15c-.83 0-1.5.67-1.5 1.5S7.67 18 8.5 18s1.5-.67 1.5-1.5S9.33 15 8.5 15zM12 1C5.93 1 1 5.93 1 12s4.93 11 11 11 11-4.93 11-11S18.07 1 12 1zm0 20c-4.96 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9zm5.5-11c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm-2 5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z"/>
    
    </svg>

I don't know exactly how to explain this but it behaves the same as background propagation from html to canvas

Example of the issue

html {
  width:50px;
  height:50px;
  background-color:red;
}

Fixed with gradient

html {
  width:50px;
  height:50px;
  background:linear-gradient(red,red) no-repeat;
}

Since there is a propagation, border-radius won't have any effect so an idea would be to use a radial-gradient:

html {
  width:50px;
  height:50px;
  background:radial-gradient(farthest-side,red 97%,transparent 100%) no-repeat;
}

In case you want any kind of border-radius here is another idea with more background layers:

html {
  --r:25px; /* adjust this to control the Radius (Max value = width/2) */
  --c:red;
  
  width:100px;
  height:100px;
  background:
    radial-gradient(farthest-side at bottom left ,var(--c) 97%,transparent 100%) top     right /var(--r) var(--r),
    radial-gradient(farthest-side at top    right,var(--c) 97%,transparent 100%) bottom  left  /var(--r) var(--r),
    radial-gradient(farthest-side at top    left ,var(--c) 97%,transparent 100%) bottom  right /var(--r) var(--r),
    radial-gradient(farthest-side at bottom right,var(--c) 97%,transparent 100%) top     left  /var(--r) var(--r),
    linear-gradient(var(--c),var(--c)) center/calc(100% - 2*var(--r)) 100%,
    linear-gradient(var(--c),var(--c)) center/100% calc(100% - 2*var(--r)) ;
  background-repeat:no-repeat;
}

For a non rectangular icon:

html {
  --rx:40px; /* adjust this to control the X Radius (Max value = width/2) */ 
  --ry:75px; /* adjust this to control the Y Radius (Max value = height/2) */
 
  --c:red;
  
  width:100px;
  height:150px;
  background:
    radial-gradient(farthest-side at bottom left ,var(--c) 97%,transparent 100%) top     right /var(--rx) var(--ry),
    radial-gradient(farthest-side at top    right,var(--c) 97%,transparent 100%) bottom  left  /var(--rx) var(--ry),
    radial-gradient(farthest-side at top    left ,var(--c) 97%,transparent 100%) bottom  right /var(--rx) var(--ry),
    radial-gradient(farthest-side at bottom right,var(--c) 97%,transparent 100%) top     left  /var(--rx) var(--ry),
    linear-gradient(var(--c),var(--c)) center/calc(100% - 2*var(--rx)) 100%,
    linear-gradient(var(--c),var(--c)) center/100% calc(100% - 2*var(--ry)) ;
  background-repeat:no-repeat;
}

And more fancy if you want to also simulate background-clip/background-origin

html {
  --p:15px;  /* offset from the edges*/
  --rx:35px; /* Max value = width/2 - var(--p)*/
  --ry:25px; /* Max value = height/2 - var(--p)*/
  --c:red;
  
  width:120px;
  height:100px;
  background:
    radial-gradient(farthest-side at bottom left ,var(--c) 97%,transparent 100%) top var(--p)    right var(--p)/var(--rx) var(--ry),
    radial-gradient(farthest-side at top    right,var(--c) 97%,transparent 100%) bottom var(--p) left  var(--p)/var(--rx) var(--ry),
    radial-gradient(farthest-side at top    left ,var(--c) 97%,transparent 100%) bottom var(--p) right var(--p)/var(--rx) var(--ry),
    radial-gradient(farthest-side at bottom right,var(--c) 97%,transparent 100%) top var(--p)   left  var(--p) /var(--rx) var(--ry),
    linear-gradient(var(--c),var(--c)) center/calc(100% - 2*(var(--p) + var(--rx))) calc(100% - 2*var(--p)),
    linear-gradient(var(--c),var(--c)) center/calc(100% - 2*var(--p)) calc(100% - 2*(var(--p) + var(--ry))) ;
  background-repeat:no-repeat;
}



回答2:


I couldn't reproduce the problem you have. When I insert that svg everything is fine for me. Yellow background is only as big as circle. Would be good if you could provide CodePen or JSFiddle with your problem..

Here is what you can do.

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 24 24" fill="rgb(255, 120, 50)" style="background-color: rgb(255, 255, 102); border-radius: 0%; width: auto; height: auto;">

<path d="M8 11.5c0-.83-.67-1.5-1.5-1.5S5 10.67 5 11.5 5.67 13 6.5 13 8 12.33 8 11.5zm7-5c0-.83-.67-1.5-1.5-1.5h-3C9.67 5 9 5.67 9 6.5S9.67 8 10.5 8h3c.83 0 1.5-.67 1.5-1.5zM8.5 15c-.83 0-1.5.67-1.5 1.5S7.67 18 8.5 18s1.5-.67 1.5-1.5S9.33 15 8.5 15zM12 1C5.93 1 1 5.93 1 12s4.93 11 11 11 11-4.93 11-11S18.07 1 12 1zm0 20c-4.96 0-9-4.04-9-9s4.04-9 9-9 9 4.04 9 9-4.04 9-9 9zm5.5-11c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm-2 5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z"/>

</svg>

Note that I aded

width: auto;
height: auto;

This will make background as big as svg. If this is not what you were looking for write a comment so we can resolve a problem.



来源:https://stackoverflow.com/questions/58784579/prevent-svg-background-bleed-for-icon

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!