Add logic to CSS - css

I would like to use logic in my CSS. Styles need to be applied only if a product ID is higher than a specific number, e.g:
if (data-product-id > 25) {
padding: 50px;
}
Is this possible with CSS?

No, it isn't. Attribute selectors are based on simple string matching. There is no provision for less than / greater than numerical comparisons.
The closest you could get with CSS itself would be something like:
[data-product-id="25"],
[data-product-id="26"],
[data-product-id="27"],
/* etc */
This sort of thing is better handled with JS or server-side code which adds classes to elements.

You can apply some limited logic of the like you were asking about in CSS, but I advise against it. Nevertheless, the answer below is an answer, it's better to implement your logic in Javascript.
Assuming that you have a class called data-product for all your data products, you can create this rule:
.data-product {
padding: 50px;
}
.data-product[data-product-id="1"],
.data-product[data-product-id="2"],
.data-product[data-product-id="3"],
.data-product[data-product-id="4"],
.data-product[data-product-id="5"],
.data-product[data-product-id="6"],
.data-product[data-product-id="7"],
.data-product[data-product-id="8"],
.data-product[data-product-id="9"],
.data-product[data-product-id="10"],
.data-product[data-product-id="11"],
.data-product[data-product-id="12"],
.data-product[data-product-id="13"],
.data-product[data-product-id="14"],
.data-product[data-product-id="15"],
.data-product[data-product-id="16"],
.data-product[data-product-id="17"],
.data-product[data-product-id="18"],
.data-product[data-product-id="19"],
.data-product[data-product-id="20"],
.data-product[data-product-id="21"],
.data-product[data-product-id="22"],
.data-product[data-product-id="23"],
.data-product[data-product-id="24"],
.data-product[data-product-id="25"] {
padding: 25px;
}

Related

How to create dynamic classes in less

I've been looking for the answers, but either it's not what I am really looking for, or I am not searching up properly. I want to dynamically generate the class name. Since, I use margin-top quite frequently, I have multiple classes defined with a set of rules, and I want to achieve with LESS.
I don't think is possible to create dynamic generated classes, as far as I did my research. Here is my code:
.margin-top-(#value)px {
margin-top: #value;
}
Desired Output
.margin-top-20px {
margin-top: 20px;
}
.margin-top-100px {
margin-top: 100px;
}
Just an example of what I am expecting.
Try to use mixin to achieve this.
//define the mixin
.margin-top(#value) {
.margin-top-#{value}{
margin-top:#value;
}
}
//use the mixin like this
.margin-top(20px);
U can try it here: http://winless.org/online-less-compiler

What is the use of parent selector (&) alone as a selector? Is it bad practice to use such selectors?

After reading tutorial after tutorial regarding Less (LessCSS), I was just wondering how this & operator is supposed to be used. I know it's referring the parent element like:
div {
&.fullheight {
height: 100%;
}
}
// turns into
div.fullheight {
height: 100%;
}
But I often saw this:
div {
span {
& {
padding: 1em;
margin: 1em;
}
}
}
// turns into
div span {
padding: 1em;
margin: 1em;
}
Like when using ONLY the & operator inside of a class, it represents pretty much the parent element, but is doing this bad practise since you can have the same result when you would type like this:
div {
span {
padding: 1em;
margin: 1em;
}
}
Both work, so is it bad/good practise or are each of them maybe used in different situations?
For extra clarity, below is the link to an answer where I first saw that you can write & only in a class without anything else.
LESSCSS - use calculation and return value - First post by ScottS, fourth solution in his post.
Generally writing something like below would be considered as bad practice because the & there is just redundant and does no value add at all. It just outputs the entire parent selector div span.
div {
span {
& {
padding: 1em;
margin: 1em;
}
}
}
So, you should avoid writing such selectors which use only the & (parent selector).
The other example to which you have linked is an interesting case which I would term as an educated hack to get around the variable scoping and lazy loading concepts in Less.
Assume that the same code was written without the parent selectors (like below).
#unit:em;
#basevalue:1;
#val: 1;
#setUnit: unit(#basevalue*#val, #unit);
.someAwesomeClass {
#val: .2;
padding: #setUnit;
#val: .1;
margin: #setUnit;
}
Here the #val variable is declared twice within the same block. Since Less does lazy loading of the variables, they need not be declared before being used (and) if the same variable is declared twice or more within the same scope, the last declaration would win.
When defining a variable twice, the last definition of the variable is used, searching from the current scope upwards. This is similar to CSS itself where the last property inside a definition is used to determine the value.
So, the compiled CSS output would have the value as 0.1em for both padding and margin whereas the expectation is for padding to be 0.2em and for margin to be 0.1em.
To overcome this, the author of that answer has introduced two namespaces (with no name) and has thus restricted the scoping issue. The variable defined within each nested block becomes local to that block only and so will be considered as two separate variables.
#unit:em;
#basevalue:1;
#val: 1;
#setUnit: unit(#basevalue*#val, #unit);
.someAwesomeClass {
&{
#val: .2; /* this declaration applies only within this nest */
padding: #setUnit;
}
&{
#val: .1; /* this declaration applies only within this nest */
margin: #setUnit;
}
}
As indicated by the author of that answer (in the first line), it was a workaround because there was no way to create a true function with Less.
But starting with Less v2, we can define our own custom functions in Less and use them as described in this answer by Bass Jobsen. The ability to write such custom functions should eliminate the need to write such hacks.
You can also refer to the comment by seven-phases-max in the same thread for a solution without the need for such hacks.
Bottomline is that usage of & alone as a selector is a bad practice. The solution in the linked answer was a hack which was useful in earlier versions of Less. It is still useful but there are alternate options and so & alone as a selector should be used only in extremely rare circumstances where none of the other option work.

sass bem element modifier inheriting said elements properties

I know that sass provides us with #extend method that allows me to do this:
%knob {
width: 10px;
height: 10px;
}
.house {
&__door {
&__knob {
color: inherit;
#extend %knob;
&--red {
#extend %knob;
// $1
color: red;
}
&--blue{
#extend %knob;
// $1
color: blue;
}
}
}
}
however i would prefer not to define abstract class %knob at all, would it be possible to reference/include properties defined in __knob (width and height in this case) from within its modifiers --red and --blue?
im including sassmeister snippet here to help out a bit: http://sassmeister.com/gist/58b5b4673a18ecadbba7
example here might not look like an issue but if an element with a long class name has 2 or more different groups of modifiers, and I wont create an abstract class, i sometimes end up with html tags looking like this <p class="some other classes some-house__some-door__some-knob some-house__some-door__some-knob--red">example</p> which I find not very desirable.
what i would like to achieve:
referencing parent element would alow me to reduce this string to <p class="some other classes some-house__some-door__some-knob--red"></p> without necessity of declaring an abstract %knob class
why am I hesitant about using an abstract class here:
declaring an abstract class inside __door element (http://sassmeister.com/gist/bc49e0885342e96a8fbd) gives me this result:
.house__door .house__door__knob, .house__door .house__door__knob--red, .house__door .house__door__knob--blue {
width: 10px;
height: 10px;
}
instead of desired
.house__door__knob, .house__door__knob--red, .house__door__knob--blue {
width: 10px;
height: 10px;
}
and declaring an abstract class outside of the scope its going to be used in makes the code less readable
or maybe theres a different apporach i could use in order to make my code more readable/maintainable?
while searching for an answer to my question i came to the conclusion that inheriting parent element properties/ using #extend or #include here might not be the best idea as it would work well only if an element had 1 modification at most:
in other cases if multiple modifications extended same model, and were to be used to the same html element, all of the base properties would be declared multiple times
also there is no need at all to deeply nest elements (i.e. foo__bar__baz). separating elements makes code easier to maintain.

LESS mixins vs classes

I'm looking into LESS because I definitely see some of their benefits. For instance colour declaration.
One thing I don't understand tho, and maybe I'm not getting the flow right is - why use the following LESS snippet
.radius {
-webkit-border-radius:5px;
-moz-border-radius:5px;
border-radius:5px;
}
.btn-red{
background-color:red;
.radius;
}
.btn-green{
background-color:green;
.radius;
}
...
When we can use the .radius class in the html file right away. I'm left with the impression that LESS will add a ton of duplicate code once it gets compiled.
I'm using the following, which makes more sense. Same with font-size, margins, etc... Aren't classes used in such cases?
<div class="btn-red radius">Cancel</div>
<div class="btn-green radius">Go</div>
The snippet above does not benefit from SASS/LESS capabilities that much. Lets have a closer look and check this SCSS snippet.
// Abstract placeholder.
%radius {
border-radius: 5px;
}
// Put your global styling here.
// I'm assuming that you can alter the markup and have button.btn.btn-green
.btn {
// Color modifier.
&-red {
#extend %radius;
background-color: red;
}
&-green {
#extend %radius;
background-color: green;
}
}
The CSS output will be:
.btn-red, .btn-green {
border-radius: 5px;
}
.btn-red {
background-color: red;
}
.btn-green {
background-color: green;
}
And then you have to pick up Autoprefixer and vendor-prefixes issue is solved once and for all.
Because now, you can just specify the class btn_red or btn_green and all the buttons will automatically have a radius.
Your HTML should contain only the semantics, and styling or classes referring to styling should not be part of it.
That applies to the other classes as well. If for instance, you would rename btn_red to btn_cancel, you have a meaningful classname that you can apply to any kind of cancel button. And in the CSS you can specify that a cancel button is red and a 'Go' button is green, and both have a radius, without needing to modify the HTML at all.
So, the ultimate goal is to have the HTML describe the structure and the CSS describe how that structure should look. And a CSS preprocessor is only their to make a bulky spaghetti-like CSS file more structured.
There are several benefits.
You can use more semantic class names. Rather than encoding style information directly in your class names, (btn-red, radius) you could use a single class that conveys the usage of the style, rather than its contents.
You can avoid repeating yourself.
#radius-size: 5px;
-webkit-border-radius:#radius-size;
-moz-border-radius:#radius-size;
border-radius:#radius-size;
You can parameterize it so that you'd be able to use different radiuses (radii?) in different contexts.
.radius(#radius-size) { ... }
Because there are cases that developer has-no-access or don't-want to change the markup. and the only solution is to include all props from a predefined class.
for example:
you have bootstrap loaded (then you already have .has-success and .has-error classes) and if you want to use HTML5's native form validation using input's :valid and :invalid states, you have to use JavaScript to add/remove success/error classes based on input's states. but with this feature of LESS you can include all props of success/error class inside input's states. the code for this example could be something like this:
#myinput {
&:valid { .has-success; }
&:invalid { .has-error; }
}

Applying Same Style to Multiple IDs with Same Words

I'd like to know if there's a way to apply the same styles to IDs that start with the same workds.
For example, I have #youtube_gallery_item_1, #youtube_gallery_item_2,....and the number keeps increasing, so I can't add a new ID every time I add a new item. FYI, I'm working with Wordpress and YouTube SiimpleGallery plugin.
I'd appreciate your help!
The "starts with" selector in CSS3.
div[id^=youtube_gallery_item] {
}
Note that this doesn't work in IE8 and below.
What would be a better idea would be to assign all of your #youtube_gallery_items a class, and then assign styles to that class. I'm sure that the plugin that you're using is doing this. Look at the source code, and if you see that they all have the same class, use:
.name-of-the-class {
}
You can use an attribute selector:
[id^="youtube_gallery_item"] {
color: skyblue;
}
http://jsfiddle.net/p9Ya8/
I would suggest adding a class
.youtube_gallery_item {
background: ;
width: ;
...
}
Its compatible with all browsers and is the easiest way to get around.
<div id="youtube_gallery_item_1" class="youtube_gallery_item"></div>
<div id="youtube_gallery_item_2" class="youtube_gallery_item"></div>
<div id="youtube_gallery_item_3" class="youtube_gallery_item"></div>

Resources