SVG as border-image on retina screens

2019-04-26 16:58发布

Please consider we have simple SVG file, containing code for rounded rectangle which corner radius equals 10:

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
  <rect fill="#FACE8D" x="0" y="0" width="100" height="100" rx="10" ry="10" />
</svg>

Here how it looks like in Chrome:

Now we use this image as a value for border-image property in CSS:

.box {
  @include border-image(url('rounded-rectangle.svg') 10);
  border-width: 10px;
  background: #FFF;
  width: 50px;
  height: 50px;
}

Now let's take a look on how it looks like in different browsers and devices: brilliant, the image stretched across element's boundaries as expected.

However, when we end up viewing those on devices with retina screens, we've got some total crap: SVG seems to be grown twice. All we see is one enormous corner.

If we replace that SVG with a similar PNG, everything is fine. Take a look (iOS 5.1 painted the inner parts of elements with the image color for some reason, however, this is not a subject of this question):

Live demo

The question is: can this be dealt with? Maybe, I've got some wrong SVG? Or I need to set the viewport meta-tag with some tricky stuff to stop border-image from scaling?

The problem is quite important. First of all, SVG is being popular mostly because of retinas. It is the tool to decorate things without being worried they would look like crap on doubled pixels.

Secondly, the mechanics and syntax of the border-image property is quite similar to the -webkit-mask-box-image proprietary property, using which is still the only way to round corners of blocks which contain absolutely positioned children (for example, Google Maps v3 can be rounded in Chromes and Safaries only through it). And this property is very valuable in mobile development with web components, when we need to set some tricky contour to an UI element. Sadly, by this property doubles it's SVG dimensions just like border-image.

UPDATE. Seems that this issue may be caused by updated SVG processor introduced in iOS 6.0: on retina SVG dimensions are computed in CSS pixels, while the coordinates are computed in retina ones. There are some bugs tracked that have something similar with my issue.

2条回答
啃猪蹄的小仙女
2楼-- · 2019-04-26 17:14

Forget images you can do this with simple css

.box {
  border: 10px solid #FACE8D;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
  background: #FFF;
  width: 50px;
  height: 50px;
}

Supported since iOS 3.2 ... http://caniuse.com/border-radius

If you need an image in order for the border to have a pattern, you can simply use a web format image without transparency and use border-radius on that

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-04-26 17:32

Given your update about iOS6 bugs, this approach might work:

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
  <rect fill="#FACE8D" x="0" y="0" width="100%" height="100%" rx="10%" ry="10%" />
</svg>
查看更多
登录 后发表回答