Change happens: border-image breaks in Chrome
As anyone who has worked in the front-end dev world knows, keeping up with the “new” stuff is challenging. Thankfully, the browser makers have provided vendor prefixes which allow us to use a lot of the new CSS3 properties before they are finalized. But thanks to a reader of my blog, I was made aware that Chrome (version 16), as they removed the need for a prefix on border-image, has also changed the way the property is rendered. This morning, I awoke to find my site broken in the latest version of Chrome.
When I updated this blog to “HTML5″, I took the leap and used CSS3 everywhere that I could. This post area was a prime candidate for border-image. For the uninitiated, border-image allows you to use a single image as both a border and fill for an element. All you need to do is specify how much of the top, left, bottom, right of the image will be the borders, and how those pieces should fill each area (stretching or repeating).
If you’ve ever used Fireworks, Illustrator or Flash, they all have a feature known as 9-slice scaling. Border-image is basically the same thing, but done on the fly via CSS. The rule for all posts here looked like this:
.post {
margin: 0 0 40px 0;
-webkit-border-image: url(images/article-background-stretch.png) 29 50 55 32 round round;
-moz-border-image: url(images/article-background-stretch.png) 29 50 55 32 round round;
border-image: url(images/article-background-stretch.png) 29 50 55 32 round round;
border-width: 29px 50px 55px 32px;
}
In keeping with best practices, you can see that I have listed the official property (without the vendor prefix) last, so that as browsers drop the need for the vendor prefix, they will simply read the last property – and the change will be seamless. Except in the case where all browser vendors are rendering a property different than the spec—thus lulling us into believing their rendering is correct when it is not.
There is actually an additional value in the spec called “fill”. The “fill” keyword instructs the browser to render the middle of the image as the background of the element. Without the keyword, the middle remains transparent (ie, the background-image or color is rendered instead). If there is no background-image or color defined for the element, it is simply transparent. Till now, all browsers have ignored the lack of the “fill” attribute and rendered the middle regardless. The code above worked perfectly—but it was based on improper rendering.
Chrome (actually, the change was made in Webkit) has recently changed their implementation of the border-image “fill” value as described in the spec. This is good, but it will ultimately break a lot of sites since many of us left the fill attribute off since vendors were ignoring it. Sloppy, sure. But it worked… until today.
So, dive back into your code and add the “fill” keyword if your site suddenly looks like swiss cheese. But you’ll want to (for now) only add the fill value to the non-prefixed version, as the addition of the value currently breaks Firefox if added to the -moz version of your rule (hat tip to @chriseppstein for that little nugget). My post class now looks like this:
border-image: url(images/article-background-stretch.png) 29 50 55 32 fill round round;
“fill” tells Chrome (and eventually other browsers) to render the center of your image as the background of the element. The two “round” values instruct the browser to tile the images on the x- and y-axis.
December 23rd, 2011 at 4:25 pm
And that’s what I get for not going back to check on my bugs. I filed this against Chromium back in October: http://srewis.me/uiQlAy It was marked as a regression—and they filed it on webkit: http://srewis.me/vpwkco (I didn’t think about it again—thinking they’d fix it). However, today I saw that a note was later added that webkit has decided to honor the spec and change its implementation. I reckon that means Safari will do this soon as well.
In truth, I like the change. You don’t always want your background controlled by the border-image … but I now have to remember all the sites I’ve used border-image on to check for holes. Yowza!
January 28th, 2012 at 1:27 pm
The background is still missing on posts viewed on your site with IE9. Makes even leaving this post really difficult. I used the Garbage Filter that showed one post for JQuery, but it appeared as though nothing was coming up! It took me a few tries to realize that the text was just blending into the background. I had to highlight the entire post to be able to read your instructions for updating JQuery mobile files in Dreamweaver. (Thanks for that post)
February 2nd, 2012 at 4:41 pm
It seems to be an issue with your internet connection. I saw this originally – panicked, checked my CSS and IECC’s – only to refresh the page and everything was fine.
March 5th, 2012 at 1:28 pm
[...] border-image introduced a similar situation recently: WebKit changed its semantics and required a `fill` keyword to match previous behavior. Sounds like trouble, but this change happened when the unprefixed variant was exposed, matching implementor best practices of changing a feature. The result: Greg Rewis of Adobe blogging that Chrome broke his site. [...]
March 7th, 2012 at 2:44 am
Unfortunately, Opera does not support the fill keyword yet – so your blog is going to show up without text background for now :-/
I’ve given an internal bug report a small kick on your behalf..
March 7th, 2012 at 6:39 am
Can you add -o- prefix so that site is readable in Opera? Do it for the Bruce that you have on the header picture. :)
March 7th, 2012 at 6:47 am
(Would be nice if you added an -o- prefixed version without the fill keyword though :-) )
May 14th, 2012 at 11:36 pm
Just read this article, your website is very beautiful, almost entirely with CSS3 background image, there may be some rotate elements in it. Prior seems these new elements can really replace sections.
June 19th, 2012 at 7:41 am
Thank you, also updated my blog for HTML5 and did not know what to do to specify the boundaries in the image, congratulations for the information.
July 22nd, 2012 at 4:26 am
hey dude, thanks for the hint, that really helped be. however, i’ve got a hint for you as well. you’ll find your site in broken in opera.
you have to add a border-image property with the -o- prefix to see it working in opera. atm, opera ignores the missing fill attribute like firefox does.
July 22nd, 2012 at 4:29 am
that’s weird. after sending that comment, the border image appeared for me as a opera user too. maybe there was some sort of loading problem the first time i opened the site. so, i guess you can ignore these comments. :)
July 22nd, 2012 at 4:28 pm
LOL – actually, you were correct, I had left off the -o- prefix. I must have been fixing it when you looked again. If I had been using Sass (which I do for every project now), my mix-in would’ve kept the problem that from happening to begin with. ;-)
September 18th, 2012 at 12:32 pm
Life Saving! Thank you for the info on the “fill” change, my site broke but only on FF and it was driving me nuts!
October 5th, 2013 at 3:29 pm
[…] border-image introduced a similar situation recently: WebKit changed its semantics and required a `fill` keyword to match previous behavior. Sounds like trouble, but this change happened when the unprefixed variant was exposed, matching implementor best practices of changing a feature. The result: Greg Rewis of Adobe blogging that Chrome broke his site. […]