防止SVG背景出血图标? [英] Prevent SVG background bleed for icon?

查看:59
本文介绍了防止SVG背景出血图标?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标是防止SVG图标的背景出血,使它们可以显示为独立文件.许多类似问题的答案都建议在SVG元素周围放置DIV或其他容器以防止流血,但目的是使SVG图标独立存在而不依赖容器.

rect元素用作背景元素并不可靠,因为此方法在某些视口宽高比方面会中断.

这可能吗?

注意:要查看该缺陷,必须下载并在浏览器中打开SVG文件.使用JSFiddle/CodePen隐藏了问题,因为这些站点将SVG封装在了一个容器中(该容器可以解决出血问题).

在此处下载SVG: https://gofile.io/?c=eKzjk7

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> 

理想的输出:

实际输出:

解决方案

使用渐变并禁用重复项可避免这种情况:

 <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> 

我不知道该怎么解释,但它的作用与从html到画布的背景传播

问题示例

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

固定渐变

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

由于存在传播,所以border-radius不会产生任何影响,因此可以使用radial-gradient:

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

如果您想要任何border-radius,这是具有更多背景层的另一种想法:

 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;
} 

对于非矩形图标:

 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;
} 

如果您还想模拟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;
} 

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:

解决方案

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;
}

这篇关于防止SVG背景出血图标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆