This should be simple, but I'm having trouble finding the search terms for it.
Let's say I have this:
<div class="a c">Foo</div>
<div class="b c">Bar</div>
In CSS, how can I create a selector that matches something that matches "(.a or .b) and .c"?
I know I could do this:
.a.c,.b.c {
/* CSS stuff */
}
But, assuming I'm going to have to do this sort of logic a lot, with a variety of logical combinations, is there a better syntax?
is there a better syntax?
No. CSS' or operator (,) does not permit groupings. It's essentially the lowest-precedence logical operator in selectors, so you must use .a.c,.b.c.
Not yet, but there is the experimental :is() (formerly :matches()) pseudo-class selector that does just that:
:is(.a .b) .c {
/* style properties go here */
}
You can find more info on it here and here. Currently, most browsers support its initial version :any(), which works the same way, but will be replaced by :is(). We just have to wait a little more before using this everywhere (I surely will).
For those reading this >= 2021:
I found success using the :is() selector:
*:is(.a, .b).c{...}
If you have this:
<div class="a x">Foo</div>
<div class="b x">Bar</div>
<div class="c x">Baz</div>
And you only want to select the elements which have .x and (.a or .b), you could write:
.x:not(.c) { ... }
but that's convenient only when you have three "sub-classes" and you want to select two of them.
Selecting only one sub-class (for instance .a): .a.x
Selecting two sub-classes (for instance .a and .b): .x:not(.c)
Selecting all three sub-classes: .x
No. Standard CSS does not provide the kind of thing you're looking for.
However, you might want to look into LESS and SASS.
These are two projects which aim to extend default CSS syntax by introducing additional features, including variables, nested rules, and other enhancements.
They allow you to write much more structured CSS code, and either of them will almost certainly solve your particular use case.
Of course, none of the browsers support their extended syntax (especially since the two projects each have different syntax and features), but what they do is provide a "compiler" which converts your LESS or SASS code into standard CSS, which you can then deploy on your site.
Related
I'm getting into scss and have been trying to apply most of my styles through variables.
There is certain variables that I want with multiple styles. For example something related to fonts.
I want all 12px size fonts to be red.
I declared a variable like
$font-12: (font-size: 12x, color: red)
Obviously I can't apply this variable like normal ones since it includes multiple styles.
Is this the correct way to declare a variable like this?
Can I even apply this variable like this?
If not, what is the correct way to apply related styles using scss?
Thanks.
You can do this via mixins.
#mixin font-12(){
font-size: 12px;
color: red;
}
Documentation: https://sass-lang.com/guide
However you can also do this in native CSS.
Simply create a utility class (this is a normal css class, I call it a utility class because it's reusable):
.font-12 {
font-size: 12px;
color: red;
}
And apply this class to any elements you want IE:
<div class="card font-12"> ..some card... </div>
<h3 class="card-title font-12"> .. some card title.. </h3>
I'm sorry, I would have liked to comment alex067's answer but as I'm not very active here my reputation would not suffice to comment therefore I have to post it as an answer:
Using a mixin is exactly the correct answer.
BUT: I strongly advise against the second proposed option!
While is is technically correct, doing it that way defeats the whole purposes of using CSS in the first instance. We could more or less go back to using old-style font-color tags etc. if we would go about it this way.
CSS is made to abstract content/semantics from design for a host of very good reasons. If you want to go the pure CSS way (no SASS) at least name your style something like 'unimportant' or 'by-line' so that it could make sense when you redefine it for different screens, high-contrast schemes, screen-reader output etc.
[With Bootstap and all those other bloody frameworks out there it seems that nobody cares about clear accessible structure and using stuff the right way; and my struggle for doing things the intended way may be futile - still I feel the need to fight for it.]
If I had a css selector such as #subtab-1, #subtab-2 etc
I could make the wildcard selector as suchdiv[id^='subtab-']
But I cannot figure out how to make a wild card for selectors such as
#subtab-1-sub1
#subtab-1-sub2
#subtab-1-sub2
#subtab-2-sub1
#subtab2-sub2
#subtab2-sub-3
etc...
How can you make something like:
div[id^='subtab-*tab-*'] (*=wildcard)
If I am understanding your question correctly, you are trying to select all elements whose id starts with subtab- followed by a number, followed by -sub followed by another number. It also sounds like you want this selector to not match #subtab-1, only things that have a suffix like #subtab-1-sub1.
This cannot be done with CSS. CSS does not supply a selector that will allow wildcards. You can however hack something together that comes pretty close.
Hacky selector that might work
[id^="subtab-"][id*="-sub"] would match any id that starts with subtab- and also contains -sub somewhere in the id. This will probably work but could cause false positives on things like #subtab-1-subtle or #subtab-something-sub2, #subtab-sub, etc.
Another hacky selector that might work
Making the assumption that #subtab-?-sub? elements are always contained inside of #subtab-? elements and that #subtab-? elements can never contain another #subtab-? element, you could use the child combinator to target them: [id^="subtab-"] > [id^="subtab-"]
Relying on a class instead
A better solution would probably be to give all of the elements you are trying to target a common class, for instance <div class="subtab-sub">, then selecting them all would be as easy as .subtab-sub. Using a class would also yield much faster performance than using attribute selectors.
All the ids start with subtab so use
div[id^='subtab']
I'm not sure you want to use IDs constructed in this fashion as a way to address elements in your HTML. I'd experiment with using classes such as subsubtab, and you could try using the nth-child pseudo-class to individually address subtabs or subsubtabs:
<div class="tabs">
<div class="subtab">
<div class="subsubtab">...</div>
<div class="subsubtab">...</div>
...
</div>
<div class="subtab">
...
</div>
</div>
Then, your CSS would look like
div.subsubtab { color: brown; }
or
div.subtab:nth-child(2) { border: 1px solid red; }
Have a look into this jQuery Selector
I think it can work.
I read this tutorial on using regular expressions with CSS selectors and am trying to extrapolate: Is there a CSS shorthand to do the following? I want to select all div's with class of "foo" that have either an additional class of "a", "b", "c", or "d".
.foo.a,
.foo.b,
.foo.c,
.foo.d {
/* stuff */
}
something like:
.foo[class~='a','b','c','d'] {} ?
It's not possible, currently (with the Selectors 3 recommendation). There isn't a full-fledged regex grammar for CSS, nor is there a way to crunch down parts of multiple selector lists.
Selectors 4 proposes a new :matches() pseudo-class based on Mozilla's original :any() implementation (see this answer for a bit of history):
.foo:matches(.a, .b, .c, .d)
Of course, don't expect browser support for this yet. I might even forget to update this answer when that time comes but... we'll see.
Maybe .foo[class~='a'][class~='b'][class~='c'][class~='d'] ?
No, your first way of writing it is the correct way. You can only search for one match at time with an attribute selector so the closest thing that's a mixture of your two methods is:
.foo[class~="a"],
.foo[class~="b"],
.foo[class~="c"],
.foo[class~="d"] {
/* stuff */
}
Which really isn't shorthand or anything :P The best way to select by classes is just the ordinary way with a .className. Attribute selectors are only really helpful for selecting other attributes, or if you have a class that begins with a certain word and are using css3. For example you could use something like:
.foo[class^="mah-class"]{ }
Which would match mah-class-a mah-class-b mah-classAHHH... etc
Example you need to float a bunch of elements.
Option 1 - Chain elements
#elm1, #elm2, #elm3, #elm4 {float:left}
Option 2 - Add a similar class to elements
.float {float:left}
Option 3 - Add style to class individually
#elm1{float:left}
#elm2{float:left}
#elm3{float:left}
#elm4{float:left}
I prefer 1 but I don't know how much of a speed impact it has, are there any other options? Whats the convention for this?
http://css-tricks.com/efficiently-rendering-css/ Seems to say that IDs are the most efficient, although IMHO I would think the class is cleaner and more accurately represents what you are trying to express.
From Google's article # http://code.google.com/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors
"Avoid a universal key selector.
Allow elements to inherit from ancestors, or use a class to apply a style to multiple elements."
So, I think best practices says use a class. Its clean and readable IMHO.
Use option two (classes) for the global cases. That's what class selectors are meant to do.
Use the ID for styling specific differences. This is what ID selectors are meant to do.
.myclass {
float:left;
height:10px;
}
#elem2 {
height:69px;
color:#ABCDEF;
}
The whole purpose of css is to free html from presentation. Thus the semantic approach is always the good one.
If you use .float { float:left } you might as well use style="float:left"... (okay this is an exageration, but the point is that the less style classes you use the better the separation between presentation and information)
As previously mentioned, the best approach is to semantically identify and classify your html code and then use DOM relationships
#elements {
float:left;
}
#elements li {
color:#ABCDEF
}
#elements li.odd {
color:#123456
}
Most CSS minimizer and "cleaners" will do your first option. In my opinion, it's much better than creating a new class to add to a bunch of elements just for style and it's a million times better than your last option.
In CSS, if it already has an ID or a class, you can apply style to it. So, comparing option 1 to option 2, option 1 should be your better choice. You don't have to go back through your code and add classes to elements that already have IDs and you don't have to juggle style between the ID and the class for the same element in your stylesheet.
As far as speed is concerned, I don't think there is much difference between the 3 options. I think it's more of a maintainability question. It seems like option 1 is going to be easiest to maintain of the options so that's probably what I would go with.
There are certain trade-offs involved. Generally, anything ID-based is believed to be faster, especially as the pages grow heavier. On the other hand, http://net.tutsplus.com/tutorials/html-css-techniques/object-oriented-css-what-how-and-why/ and similar article authors believe that using classes for common rules makes sense and should be used. The speed difference is often negligible and carefully used classes make maintaining and updating design a lot simpler.
I'm trying to find out what is the best practice for naming and casing css classes and ids, especially multiple word names.
So for instance, say I have a <div> that I want to name "character skills".
It seems like there are 3 choices: "characterskills", "character_skills", or "character-skills".
Which one of these is the industry standard for naming css classes and ids?
What's the best practice for splitting multiple words in css names?
Also is it a best practice to always use all lowercase for css names, because they are case-insensitive?
I tend to use the hyphenated style as well. I mainly use that style since CSS properties follow the same casing. Similarly, JavaScript functions and variables tend to use lower camel case. For example, to change a CSS property in JavaScript, you would type object.style.textDecoration, but in CSS, that property would be changed with text-decoration.
I use lowerCamel for class names and UpperCamel for IDs. This is quite important and I'm beating this old answer because IMO the hyphenated style should be discouraged, even underscore is better than hyphenated.
Why? Because every other language can't have hyphenated variable names. For e.g., your IDE may or may not pick up auto-completion properly. (My IDE can't, it's VI :P)
CSS being closely related to JavaScript, hyphenated classname also make it difficult to interop with JavaScript. Consider the following (contrived) jQuery:
// For each of the following class, perform a function
var funcs =
{
main: function(){ /* ... */},
toolbar: function(){ /* ... */ },
// Oops, need to use a quote because there's this hyphenated name
'customer-info': function(){ /* ... */ }
};
// Woot, a O(n^2) function
for(var className in funcs)
{
var func = funcs[className];
// maybe if we named it $('#some-selector')? The hyphen suddenly feels
// like some kind of operator to me. Makes me nervous :/
$('#SomeSelector div').each(function()
{
if($(this).hasClass(className)) func();
});
}
There's no clear advantage to using the hyphenated style other than subjective aesthetics. The disadvantages are that it stands out from every other programming language (OK, CSS may not be a programming language, oh well..) and that it is technically incorrect.
The correct (huh?) way to represent a space is underscore. Consider this phrase "a self-addressed letter," how can I convert the spaces?
a_self-addressed_letter (correct, preserves the original meaning)
a-self-addressed-letter (ouch! if we convert it back we get "a self addressed letter"!)
Also is it a best practice to always use all lowercase for css names, because they are case-insensitive?
I guess in this case, it's a best practice to always use PascalCasing because it aids readability.
I personally use the hyphenated style (i.e. some-class) but you should simply choose what you feel is best and be consistent. It is purely an issue of aesthetics.
I see the following casing styles a lot:
characterSkills,
CharacterSkills
But, at the end of the day it doesn't matter which style you pick. Just be consistent within your own app.
I've seen several different answers to this question, depending on who you ask. Ranging through all of the possibilities you mentioned and probably more. The one I see referenced most often, however is to use underscores (character_skills) and all lowercase.
The one answer thats always mentioned though and arguably more important than which method you choose, is to pick one and stick to it throughout. Keeping things uniform throughout allows you to avoid confusion and other problems later.
I use lowerCamelCase for classes, and UpperCamel for IDs, like so:
#HeaderLogo { ... }
.pullQuote { ... }
But it really makes absolutely no difference so long as you're consistent :) Oh, and try to stick to one-word class names where possible - you can always combine classes, like so:
.boxout { border: 1px solid; padding: 10px; }
.emphasised { font-weight: bold; }
.subtle { font-size: small; }
.boxout.emphasised { background: yellow; }
.boxout.subtle { color: gray; }
...which I prefer, as you can have your "base" classes hold core definitions, keeping your CSS smaller, and reducing the overall number of classes you have to remember when designing pages.
After reading examples and making my own mistakes, I landed on this solution for myself:
Use hyphens to show hierarchy e.g. #products-MainContent {} or #maincontent-Summary {}. To me this means that MainContent is a child of the products div.
Capitalise each word after the first element in the heirarchy for IDs. Use all lowercase for classes e.g. #summary-Statistics (ID) or .summary-statistics (class)
This works for me for now. I don't want to use hyphens to separate words because I think hyphens should show dependency/relationships. Also I don't want to mix up IDs and Classes because they look similar so I changed the case in which they were written.
I recommend using the BEM (Block Element Modifier).
Retrieved from its website:
BEM — Block Element Modifier is a methodology that helps you to create
reusable components and code sharing in front-end development.
For more details please visit its website documentation:
http://getbem.com/naming/