13

Is it possible to access an HTML attribute value in SASS? I have a line of code that says

<ul id="my_id" data-count="3">

where the 3 is the result of some jQuery stuff. I need the 3 to calculate some CSS. How can I save it as a SASS variable?

Alternatively, is there a way of counting the number of child elements of a certain parent element? Say I have this code:

<ul id="my_id" data-count="3">
    <li>First list item</li>
    <li>Second list item</li>
    <li>Third list item</li>
</ul>

(As you might have guessed, the value of data-count matches the number of list items.) Can SASS count the list items and save that number as a variable?

Any ideas would be greatly appreciated.

New Alexandria
  • 6,951
  • 4
  • 57
  • 77
joschaf
  • 515
  • 2
  • 6
  • 14
  • http://caniuse.com/#feat=css-counters – SLaks Nov 21 '12 at 20:59
  • Interesting, I didn't know about that ... Unfortunately it only seems to work with `content:`, but I need the integer to calculate stuff. Anyway, I learned something today, so thanks. – joschaf Nov 21 '12 at 22:52

3 Answers3

14

Sass is just a CSS generator. It doesn't really interact with your HTML, so you can't use HTML attributes as Sass variables.

However, CSS can select based on attributes. So it will be more long-winded than you might like, but you can do something like

ul[data-count="3"]:after
  content: "There were three items in that list!"

And I think if you're willing to limit yourself only to a subset of very recent browsers, you can use the CSS calc() function along with attr() to use the attribute in CSS-based calculations. But that's pretty bleeding edge.

† To be perfectly honest, I have no idea which versions of which browsers have fully implemented this. I'm pretty sure Firefox has it, though I've not used it, and I have no idea about other browsers. It is certainly not well-supported, at any rate.

Chuck
  • 234,037
  • 30
  • 302
  • 389
  • 1
    @SLaks: It's specifically the interaction of `calc()` and `attr()` that I don't believe to be well-supported. `calc()` itself is pretty recent, but it's nowhere near as exotic as support for using an attribute in the calculation. – Chuck Nov 21 '12 at 21:12
  • Thanks, Chuck, `calc()` and `attr()` are news to me, and they might be useful for some other trouble I'm having. But since they only seem to work with `content:` I can't use them for the task at hand because I need the integer to calculate. But thanks anyway. – joschaf Nov 21 '12 at 22:58
5

It seems like you are trying to get the number of items inside your unordered list in CSS (maybe to change their size according to the number of siblings?).

Indeed, you cannot use a data-attribute as a Sass variable. However there is a pure CSS way to apply conditional styles given the number of items in the parent. Plus, it is very easily written in Sass.

Let's say your maximum number of items in your list is 10 and you want to compute the size of li tags based on the number of li tags there is in your list.

@for $i from 1 through 10 {
    li:first-child:nth-last-child(#{$i}),
    li:first-child:nth-last-child(#{$i}) ~ li {
        width: (100%/$i);
    }
}

This will output the following CSS:

li:first-child:nth-last-child(1),
li:first-child:nth-last-child(1) ~ li {
    width: 100%;
}
li:first-child:nth-last-child(2),
li:first-child:nth-last-child(2) ~ li {
    width: 50%;
}
li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li {
  width: 33.33333%;
}
li:first-child:nth-last-child(4),
li:first-child:nth-last-child(4) ~ li {
    width: 25%;
}
li:first-child:nth-last-child(5),
li:first-child:nth-last-child(5) ~ li {
    width: 20%;
}
li:first-child:nth-last-child(6),
li:first-child:nth-last-child(6) ~ li {
    width: 16.66667%;
}
li:first-child:nth-last-child(7),
li:first-child:nth-last-child(7) ~ li {
    width: 14.28571%;
}
li:first-child:nth-last-child(8),
li:first-child:nth-last-child(8) ~ li {
    width: 12.5%;
}
li:first-child:nth-last-child(9),
li:first-child:nth-last-child(9) ~ li {
    width: 11.11111%;
}
li:first-child:nth-last-child(10),
li:first-child:nth-last-child(10) ~ li {
    width: 10%;
}

Basically, this gives the li tags a width of:

  • 100.0% when there is only one li tag
  • 50.00% when there are 2 li tags
  • 33.33% when there are 3 li tags
  • 25.00% when there are 4 li tags
  • 20.00% when there are 5 li tags
  • 16.66% when there are 6 li tags
  • 14.28% when there are 7 li tags
  • 12.50% when there are 8 li tags
  • 11.11% when there are 9 li tags
  • 10.00% when there are 10 li tags

For a live example, please refer to this demo I did using the same trick. I hope it helps.

888
  • 3,246
  • 8
  • 41
  • 60
  • How does chaining first-child with nth-last-child work exactly? Having trouble wrapping my head around that. – reneruiz May 16 '13 at 17:56
  • Nevermind, I [found it](http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/) – reneruiz May 16 '13 at 20:38
1

If you want to access an HTML attribute from CSS, you can use attr()

Check the doc

Roman Panaget
  • 1,578
  • 12
  • 21