0

There are 3 tables: #table1, #table2and #table3.

Is there a way to specify the style for all 3 table without the use of css class?

For instance, can we combine the following selectors:

#table1 tbody td a, #table2 tbody td a, #table3 tbody td a {
    /* rules here */
}

into something like:

(#table1, #table2, #table3) tbody td a {
    /* rules here */
}
damian
  • 5,314
  • 5
  • 34
  • 63
  • The best you can get with plain CSS is `#table1 a,#table2 a,#table3 a` although even that's not 100% equivalent to what you have. – j08691 Apr 08 '15 at 15:28
  • 1
    If you only want to write short selector in source and don't mind the long selectors in production code, give SASS a try. You can write nested selectors `#table, #table, #table { tbody td a { /* style */ } }` – MayThrow Apr 08 '15 at 15:34
  • To extend @rzr's suggestion, pretty much _any_ CSS preprocessor can handle this with ease. If this is functionality you need on any kind of regular basis, I'd look into preprocessors. But, considering that you don't want to use a class, I would assume a preprocessor is way more overhead than you're looking for :P – Carrie Kendall Apr 08 '15 at 15:37
  • 1
    This was asked just yesterday: http://stackoverflow.com/questions/29502927/how-to-parameterize-css-selectors but the dupe target there is not particularly helpful in this case given that the three IDs seem to have something in common. – BoltClock Apr 08 '15 at 15:38
  • I would recommend to use class instead of ID if you can. i.e. ``, `
    ` and css like this `.table {}` for shared rules, `.table1 {}`, `.table2 {}` for individual rules. Although this doesn't really answer your question.
    – Stickers Apr 08 '15 at 15:39

4 Answers4

4

You could use an attribute selector:

[id^="table"] tbody td a {
   /* your code */
}
damian
  • 5,314
  • 5
  • 34
  • 63
  • 2
    You can do that, but it's terribly inefficient. – Randy Hunt Apr 08 '15 at 15:32
  • 1
    @RandyHunt But will it really be noticeably inefficient? No. – Josh Crozier Apr 08 '15 at 15:32
  • @RandyHunt He's using id's for the tables and we're talking about efficiency? – damian Apr 08 '15 at 15:34
  • Depends on what else is going on in the page, how powerful the computer/device is that is rendering the page, and how often reflows happen. – Randy Hunt Apr 08 '15 at 15:35
  • @enyce12 IDs are super fast selectors. – Randy Hunt Apr 08 '15 at 15:35
  • You're missing the `a` BTW. – j08691 Apr 08 '15 at 15:36
  • @RandyHunt Sure, but they enormously increase the specificity. – damian Apr 08 '15 at 15:38
  • @RandyHunt what are you classing as a reflow? Any docs to show their impact on attribute selectors? It's generally the definitions of those styles that cause issues with reflows (font size, percentage and em measurements, etc), not the selectors themselves... – BenM Apr 08 '15 at 15:39
  • 1
    @enyce12 I don't disagree. But this is obviously not a case where the developer wants to do what's best, given that the request includes _not adding a class_. – Randy Hunt Apr 08 '15 at 15:39
  • 1
    @RandyHunt That's why I proposed an attribute selector ;) – damian Apr 08 '15 at 15:40
  • @BenM Any time a browser has to parse a set of rules, it will have to evaluate _every_ element in the DOM, searching for a matching attribute. This, compared to IDs and classes, which are indexed. – Randy Hunt Apr 08 '15 at 15:42
  • I would at the very least suggest adding the `table` tag in front of the attribute selector. – Randy Hunt Apr 08 '15 at 15:42
1

The way to do this in CSS will be the :any selector:

:any(#table1, #table2, #table3) tbody td a {
    color: red;   
}

This is currently experimental, and only supported in Firefox, Chrome/Opera and Safari. Since it's prefixed versions only this probably won't save you any typing over just listing the rules for each ID, as you need to have a rule for each prefix:

:-moz-any(#table1, #table2, #table3) tbody td a {
    color: red;   
}
:-webkit-any(#table1, #table2, #table3) tbody td a {
    color: red;   
}

Demo.

As BoltClock has pointed out in a comment, the current CSSWG proposal for this functionality is the :matches() pseudo-class, here's a nice article which explains the selector and also how to get the same results with Sass.

robertc
  • 74,533
  • 18
  • 193
  • 177
  • 1
    FYI, `:any()` is specced as `:matches()`. There will probably not actually be an unprefixed `:any()`. – BoltClock Apr 08 '15 at 15:45
  • It's interesting to note that the way it's currently implemented, it's simply expanded into its full comma-separated forms, i.e. `#table1 tbody td a, #table2 tbody td a, #table3 tbody td a` as given in the question. Essentially, this is syntactic sugar with negligible overhead. – BoltClock Apr 08 '15 at 15:46
  • @BoltClock Cool, will update the answer with this info – robertc Apr 08 '15 at 15:49
0

If it's essential to do this, you can use an attribute selector as follows:

[id^="table"] td a {

}

However, you're generally better off using a class definition for applying the same style to multiple elements. It is not only more performant, but scales better for future use, and means that your element IDs are protected.

For example, what if you wanted to add another element with the ID of table-view, now your CSS rule will be imported, and without using a more specific selector, or the dreaded !important statement, you're stuck with it!

BenM
  • 52,573
  • 26
  • 113
  • 168
0

You can comma separate selectors, but only the full selector so: #table1 tbody td a, #table2 tbody td a ... not(#table1, #table2, #table3) tbody td a.

Why not use a class though? If you're applying the same CSS to multiple tables, it's easier, and from a re-usability standpoint, it's way easier when you decide you need to add table 4 in six months.

Always design for what you might end up with, not what you currently have.

Carrie Kendall
  • 11,124
  • 5
  • 61
  • 81