Applying css rules if under a specific class or id - css

Is it possible to define several rules under a class without having to write the class before each time. For example:
.container-class .id-1 // {rules}
.container-class .id-2 // {rules}
.container-class .id-3 // {rules}
Is it possible to avoid having to write .container-class every single time?

Only if you use a preprocessor language like LESS or SASS
With LESS you can write this:
.container-class {
.id-1 { }
.id-2 { }
.id-3 { }
}
To achieve what you want.
You can read more here: http://lesscss.org/

If the rules for all your elements are the same, what you can do at the moment is:
.container-class .id-1,
.container-class .id-2,
.container-class .id-3{
/*...*/
}
There is an experimental property :any() which could be used.
Selectors Level 4 specifies the pseudo-class :matches().
.container-class :-moz-any(.id-1 .id-2 .id-3){
/*...*/
}
/* standards compliant*/
.container-class :matches(.id-1 .id-2 .id-3){
/*...*/
}
Problem with this atm is, that you have to use vendor prefixes which makes this a bit useless, because you have to put each vendor prefix into a separate rule block.
If you have different rules for those elements, you can't group them. You can shorten it with LESS or SASS, but in the end, it still compiles to the verbose form.

Related

How to make parent selector interpolated in the middle of nested selector in sass/scss

I'd like to get the result below using sass nesting
css
.box {...}
h3.box-title {...}
I tried code like this, but it causes an error.
sass
.box {
h3.&-title {
...
}
}
I'd like to know if there is any way to do this keeping sass nesting?
I know that it's not good to write HTML element on CSS,
but I'm working on a project that I can't modify existing CSS and need to overwrite them.
Try this:
.box {
#at-root h3#{&}-title {
...
}
}
I used the sass interpolation #{} to compile expectedly the value of &, and #at-root to prevent the prefix .box (prevent resulting to .box h3.box-title because we want h3.box-title only - without the prefix .box)
Here's the captured result:
Anyway, I don't think this is a good practice to write sass/scss
.box
and
.box-title
are two different class names. Unless h3.box-title is a child of .box, honestly, there's no reason you should be nesting it.
Also & is used to look for additional class names. i.e.
.box {
&.box-title {}
}
would be
.box.box-title {}

BEM: adding modifier to already existed modifier

I'd been confused by simple scenario when I was working with BEM.
There is a base button in example:
.button {
// styles for button
}
and its modifier with more specific styles:
.button.button_run {
// additional styles for this type of button
// i.e. custom width and height
}
One moment I realize that I need modifier for button_run, let's name it like button_run_pressed:
.button_run_pressed {
// more styles, i.e. darker background color
}
The problem is that it's not correct to name the last element as I did above button_run_pressed according to BEM conventions. But I need to add "pressed" styles only to "run" button, not for all buttons by writing class like button_pressed and mixing modifier button button_run button_pressed.
How should I refactor my code to match BEM conventions?
According to http://getbem.com/naming/, the modifier classes are initiated with two hyphens (--). So a modifier for .button should look like
.button--modifier { /* ... */ }
In your case, I would suggest choosing the following names:
.button {}
.button--run {}
.button--run-pressed {}
Notice, that I also decoupled the modifier classes from the block class, which is more according to BEM rules. You want to avoid creating classes which depend on others to work.
Since you added less as a tag to the post, here's how this could look in less or scss:
.button {
// button styles
&--run {
// modified styles
}
&--run-pressed {
// more modifiers
}
}
This would result in the classnames I wrote above
Firstly, the name should be .block--modifier or .button--run
If you want it only works with both modifier run and press, you should name it as
.button.button--run.button--pressed
Hope this help

difference in id selector and namespace in less

I am trying to learn less to reduce the pain of repetitive css. One thing that confuses me is the syntax of namespace in less. To my understanding, less is compatible with css, therefore
#myelement-id{}
is an id selector. On the other hand, less supports namespace by specifying
#namespace{}
So, when I read a less file, how can I tell which "#" is for id selector and which is for namespace?
Thanks for your help.
There is no difference. A #id or .class can be used as a namespace call to access its other classes or mixins. To make it different, you need to make it a mixin. So either of these is valid:
#namespace {
.test {
prop: 1;
}
}
#namespace() {
.test {
prop: 1;
}
}
The first will produce css output as an id selector, the second will not. But either can access the nested values, so either of these work inside a selector block to access the .test class via this:
.class {
#namespace > .test;
}
But the output will be different, as the first will be:
#namespace .test {
prop: 1;
}
.class {
prop: 1;
}
And the second just:
.class {
prop: 1;
}
More over, there's no difference even between a mixin and a namespace. A namespace can also be parametric (though parametric namespaces have some unusual properties/side-effects that make them differ from non-parametric namespaces). See for example #1205, #1316, #1525.
Basically, LESS namespace is just any ruleset that contains another ruleset(s). It's more like a logical concept/convention, not a language construction.

LESS: mixin with non-class ruleset

In LESS, I am trying to define the button.c2 ruleset, to be applied to <button class="c2">...</button> elements. This ruleset is mainly based on the button.c1 ruleset. However, the following code produces a ParseError:
button.c2 {
button.c1;// Trying to import a ruleset
... // additional rules, such as font-size: 120%;
}
It seems to me that the ParseError is caused by the fact that the imported ruleset does not refer to a class or ID ("button.c1" does not start with a "." or a "#"). From the LESS documentation:
Any CSS class or id ruleset can be mixed-in that way.
Why is there such a limitation? Is there any way around it?
The limitation might just be ease of parsing, since . or # don't show up as the first character of a normal style rule the parser automatically knows that those should be mixed in.
You could get around it by defining .c1 as a mixin and using it for both buttons:
.c1() {
// c1 rules
}
button.c1 {
.c1;
}
button.c2 {
.c1;
// additional rules
}
However, coming up in LESS 1.4.0 are :extend selectors, which will allow you to do what you want. The syntax would be:
button.c2:extend(button.c1) {
// additional rules
}

Conditional CSS rules with less, based on variable

The variable can take percentage or px values, like:
#some-var: 50px; or #some-var: 46%;
How can I define a certain set of CSS rules if the value is in pixels, and a different set of rules if the values is in percentages?
Is there something like
if(isValueInPixels(#some-var)){
// css rules here
}else{
// other rules here
}
?
I think you can use something that they call Guarded Mixins.
Try something like this...
.mixin (#a) when (ispixel(#a)) {
/* ... your pixel specific logic ... */
}
.mixin (#a) when (ispercentage(#a)) {
/* ... your percentage specific logic ... */
}
.coolStuff {
.mixin(50px);
.mixin(50%);
}
See the Guarded Mixins at http://lesscss.org/
As Adam Spicer noted the Guarded Mixins are your best solution.
However, LESS now offers a solution to group multiple guards, which will allow this to be accomplished with a single mixin.
http://lesscss.org/features/#css-guards-feature
For Example:
.mixin(#a){
& when (ispixel(#a)){
//logic
}
& when (ispercentage(#a)){
//logic
}
}
Usage:
selector{
.mixin(50px);
.mixin(46%);
}

Resources