Skip to main content
Ben Nadel at cf.Objective() 2010 (Minneapolis, MN) with: Doug Hughes and Ezra Parker and Dan Wilson and John Mason and Jason Dean and Luis Majano and Mark Mandel and Brian Kotek and Wil Genovese and Rob Brooks-Bilson and Andy Matthews and Simeon Bateman and Ray Camden and Chris Rockett and Joe Bernard and Dan Skaggs and Byron Raines and Barney Boisvert and Simon Free and Steve 'Cutter' Blades and Seth Bienek and Katie Bienek and Jeff Coughlin
Ben Nadel at cf.Objective() 2010 (Minneapolis, MN) with: Doug Hughes Ezra Parker Dan Wilson John Mason Jason Dean Luis Majano Mark Mandel Brian Kotek Wil Genovese Rob Brooks-Bilson Andy Matthews Simeon Bateman Ray Camden Chris Rockett Joe Bernard Dan Skaggs Byron Raines Barney Boisvert Simon Free Steve 'Cutter' Blades Seth Bienek Katie Bienek Jeff Coughlin

Less CSS, Relative Paths, Nested Quotes, Url() Constructs, And Post-Processing

By
Published in

This is a really tiny post, but it's something that had our team baffled for weeks. We were using an older version of RetinaJS which defined an .at2x() mixin for inserting media-query rules for retina-sized images. Everything was working great until we upgraded our Less CSS compilers; then, everything started breaking in a really weird way. After a lot of digging, we discovered that Less CSS gets a little funky when you have nested quotes that contain relative paths inside of url() constructs.

To demonstrate, here is some Less CSS that isolates the problem:

// -- Working. -- //

h1 {
	@single-quotes: "../../Meep.png" ;

	background-image: url( @single-quotes ) ;
	content: @single-quotes ;
}

h2 {
	@single-quotes: '../../Meep.png' ;

	background-image: url( @single-quotes ) ;
	content: @single-quotes ;
}

// -- Breaking. -- //

h3 {
	@nested-quotes: "'../../Meep.png'" ;

	background-image: url( @nested-quotes ) ;
	content: @nested-quotes ;
}

h4 {
	@nested-quotes: '"../../Meep.png"' ;

	background-image: url( @nested-quotes ) ;
	content: @nested-quotes ;
}

Notice that the second set of CSS rules contain values that have nested quotes - double quotes within single quotes or single quotes within double quotes. Also notice that the image paths are all relative paths that go above the current file. When we compile this Less CSS with CodeKit 2 or LiveReload (the ones I happen to use), we get the following CSS:

h1 {
	background-image: url("../../Meep.png");
	content: "../../Meep.png";
}
h2 {
	background-image: url('../../Meep.png');
	content: '../../Meep.png';
}
h3 {
	background-image: url("Meep.png'");
	content: "'../../Meep.png'";
}
h4 {
	background-image: url('Meep.png"');
	content: '"../../Meep.png"';
}

Notice that the h3 and h4 paths are completely broken, but only when used in conjunction with the url() construct; the relative paths lose their dots and one of the quotes is stripped out (leaving the string value unevenly quoted). Based on what I can gather from this GitHub thread, it appears that Less CSS is trying to do some sort of post-processing on url() values (which I don't fully understand).

Ultimately, the problem had to do with the way the older version of RetinaJS was building the paths - it was accidentally nesting quotes. The newer version of RetinaJS gets around this by not quoting its input during the JavaScript source interpolation; of course, this breaks if you don't quote your URLs. But, that's OK - if you're one of those people that doesn't quote URL values, breaking code is what you get (he says from high up on his soap box).

Want to use code from this post? Check out the license.

Reader Comments

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel
Managed hosting services provided by:
xByte Cloud Logo