CSS 3 multiple comma separated background mixin not possible #228

Closed
Tzaphkiel opened this Issue Mar 29, 2011 · 19 comments

Projects

None yet

10 participants

@Tzaphkiel

Hi,

I tried this:

.multiBg(@bg: ..image/128.jpg, @tag: ../images/noTag.png)
{
    background: 
            url(../images/corner1_128.png) bottom left no-repeat,
            url(../images/corner1_128_TL.png) top left no-repeat,
            url(../images/corner1_128_TR.png) top right no-repeat,
            url(../images/corner1_128_BR.png) bottom right no-repeat,
            url(@tag) top right no-repeat,
            #fff url(@bg) center repeat;
}

to define four corner images, a background image and a spamp/tag in a corner...
The general idea is to re-use the mixin just to specify the background and the tag/stamp...

As soon as I code and/or try to use this mixin, it does not compile anymore. I cannot give you the corresponding message since I use direct in page generation of the css using: <script src="js/libs/less-1.0.40.js"></script>

Regards
Tzaph

@cloudhead
Member

Try quoting the default arguments as so:

.multiBg(@bg: "..image/128.jpg", @tag: "../images/noTag.png")

should work fine.

@cloudhead cloudhead closed this Apr 20, 2011
@Tzaphkiel Tzaphkiel reopened this Apr 20, 2011
@Tzaphkiel

Hi, thx for looking into it...

The problem does not lie in the default arguments of the mixin, more in the parsing of the background arguments.

I believe less has a rule set that only knows of the version of background definition in CSS2 and not CSS3 where multiple backgrounds can actually be defined. It therefore does not compile properly when "background: ..." has multiple url declarations !

Tzaph

@cloudhead
Member

I'm not sure what you mean, this is the output I get (added new lines myself):

.class {
  background: url(../images/corner1_128.png) bottom left no-repeat,
              url(../images/corner1_128_TL.png) top left no-repeat,
              url(../images/corner1_128_TR.png) top right no-repeat,
              url(../images/corner1_128_BR.png) bottom right no-repeat,
              url("../images/noTag.png") top right no-repeat,
              #ffffff url("..image/128.jpg") center repeat;
}

Make sure you have the latest version, something related might have been fixed recently.

@Tzaphkiel

I've just updated from 1.0.40 to 1.0.41 and it still does not work when I add this code:

.multiBg(@bg: "..image/128.jpg", @tag: "../images/noTag.png")
{
background:
    url(../images/corner1_128.png) bottom left no-repeat,
    url(../images/corner1_128_TL.png) top left no-repeat,
    url(../images/corner1_128_TR.png) top right no-repeat,
    url(../images/corner1_128_BR.png) bottom right no-repeat,
    url(@tag) top right no-repeat,
    #fff url(@bg) center repeat;
}

and I call it this way:

<link rel="stylesheet/less" href="css/main.less" type="text/css" />
<script src="js/libs/less-1.0.41.min.js"></script>

Is there a place where I can compile it "online" and see the result or an error log ?

@Tzaphkiel

Update: I've compiled the main.less using jquery and outputting it to the console and it seems to generate the required content:

background: url(../images/corner1_128.png) bottom left no-repeat, url(../images/corner1_128_TL.png) top left no-repeat, url(../images/corner1_128_TR.png) top right no-repeat, url(../images/corner1_128_BR.png) bottom right no-repeat, url("../images/noTag.png") top right no-repeat, #ffffff url("..image/128.jpg") center repeat;

But when I use the page include, the css does not seem to be used, I get a page without any css rendering... (and no js errors)... I don't know where to look to fix this 'issue'. The fact that if I remove the multiple url(...) from the background declaration, it works seems strange...

@cloudhead
Member

Have you tried the CSS output directly?

Also you can see what LESS generates in your page by looking in your <head>, it should have created a <style> element with the css.

@Tzaphkiel

This is what I found using the inspect element of Chrome.
The only 'extra' style element that appears when the problem happens is:


    <style type="text/css" media="screen" id="less:error-message">
    .less-error-message ul, .less-error-message li {
    list-style-type: none;
    margin-right: 15px;
    padding: 4px 0;
    margin: 0;
    }
    .less-error-message label {
    font-size: 12px;
    margin-right: 15px;
    padding: 4px 0;
    color: #cc7777;
    }
    .less-error-message pre {
    color: #ee4444;
    padding: 4px 0;
    margin: 0;
    display: inline-block;
    }
    .less-error-message pre.ctx {
    color: #dd4444;
    }
    .less-error-message h3 {
    font-size: 20px;
    font-weight: bold;
    padding: 15px 0 5px 0;
    margin: 0;
    }
    .less-error-message a {
    color: #10a
    }
    .less-error-message .error {
    color: red;
    font-weight: bold;
    padding-bottom: 2px;
    border-bottom: 1px dashed red;
    }</style>

but there is no error, less-error-message class, id, element defined anywhere in the file...

@cloudhead
Member

Well, where are you calling that mixin from? If that's the only <style>, it just means it hasn't compiled anything.

@Tzaphkiel

That is the only style that is present in the generated HTML code after the whole page renders in the browser (chrome) and thus after the script has runned...

@stereomyth

This is not just an issue with multiple backgrounds, less removes the comma in any multiple attribute.

I found this problem with box shadow:

.shadow(){
  -webkit-box-shadow: @arguments;
     -moz-box-shadow: @arguments;
          box-shadow: @arguments;
}

.shadow(black 1px 1px 1px, white 1px 1px 1px inset);

Outputs as:
... box-shadow: black 1px 1px 1px white 1px 1px 1px inset
Missing the comma between the different shadows

A temporary fix is to escape the comma, but having to do that every time isn't great

shadow(black 1px 1px 1px~"," white 1px 1px 1px inset);

@marioestrada

Anyone know of a more formal way to include the comma with @arguments, Stylus has args and arguments for different handling of whole arguments. Maybe Less can implement @args and it would retain the commas passed to a function.

@json-uk
json-uk commented Apr 22, 2012

I too ran into this issue and would greatly appreciate a fix. Yes, I am aware that I can create multiple mixins, each with a specific purpose but that goes against the DRY principle that LESS and SASS are designed to solve. The escaping trick is helpful - thanks for that!

@lunelson
lunelson commented Jun 5, 2012

+1

@lazd
lazd commented Jun 27, 2012

Mark Otto of Twitter Bootstrap comments a related issue: http://www.markdotto.com/2012/04/05/comma-separated-values-in-less-mixins/

Instead of just escaping the comma, you can escape the whole argument:

.box-shadow(@shadow) {
  -webkit-box-shadow: @shadow;
     -moz-box-shadow: @shadow;
          box-shadow: @shadow;
}
.element {
    .box-shadow(~"0 1px 3px #eee, 0 5px 10px #f5f5f5");
}
@lukeapage
Member

I like the idea of args and arguments - and this has come up in a few other bugs too.

@matthew-dean
Member

This issue is a duplicate of Issue #35, the discussion of which contains other solutions to this problem than arguments-list.

@lukeapage
Member

duplicate and fixed (use .mixin-call(12px 34px, 34px 12px;); to pass commas from 1.3.2)

@lukeapage lukeapage closed this Dec 16, 2012
@strk strk pushed a commit to CartoDB/carto that referenced this issue Mar 22, 2013
@tmcw tmcw Fixing new parser reference to makeError. Fixes #228 4b8256e
@jimmy-collazos

I have a similar problem, this is my code (important: return line after comma):

test.less

h1,
h2,
h3
{
  display: block;
}

main.less

@import "test.less"

run and error:

$ lessc main.less main.css
ParseError: Syntax Error on line 1 in main.less:1:3
} display: block;

If i execute lessc test.less test.css dont have any problem

My version of lessc is 1.3.3

@lukeapage
Member

@acido69 can you add a new issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment