Sifr3 - Is it possible to override CSS styling with parent selector? - css

I would like to override setting that already defined with selecting
parent selector but I don't know how.
Say, there are 2 pages on a website like the following...
-Home page-
<body><h1 class="sifr">Home</h1></body>
-About page-
<body class="about"><h1 class="sifr">About</h1></body>
then, I have these in sirf-config.js...
sIFR.replace(fontname, {
selector: 'h1.sifr',
css: '.sIFR-root { color: #666666; font-size:29px; }'
});
sIFR.replace(fontname, {
selector: 'body.about h1.sifr',
css: '.sIFR-root { color: #FFFFFF; font-size:29px; }'
});
but it doesn't work...
If anybody help me I would appreciate.

Run the replacements for body.about h1.sifr before h1.sifr. sIFR doesn't calculate specificity but executes the replacements in-order. Replacing h1.sifr replaces all such elements, so body.about h1.sifr only finds elements that have already been replaced.

Check the order your loading CSS vs issuing the replace commands ...

I don't use Sifr, so I don't know exactly how it works. I assume that the code creates CSS code like this:
h1.sifr { color: #666666; font-size: 29px; }
body.about h1.sifr { color: #FFFFFF; font-size: 29px; }
If it does, that will override the color style for the heading in the about page, as the selector for the second line is more specific than the selector in the first line.
You can read more about specificity here.
If it doesn't work, it's because there is something in your code that doesn't look like you think it does, and it may very well be something in some other part of your code that you haven't shown here that is causing the problem.
You can use the Firebug plugin in Firefox to inspect the elements in the page to see exactly which css is affecting each element.

Related

What design philsophy led CSS away from class-level inheritance? (and reliance on #extend/#apply in sass)

It sounds like this is something that sass/less/mixins/jquery are required for right now.
What I'm looking to do is something like this:
.myClass {
color: blue;
}
h1 {
class: myClass;
}
I'm curious why this was not done already, given that CSS seems to be about inheritance/aggregation if nothing else.
Does it not make sense for some reason?
Or maybe it's just too complex?
Thanks!
...I don't know if this is the first '#extend' proposal, but it comes out because of its popularity in sass, apparently: http://tabatkins.github.io/specs/css-extend-rule/
and there is an early discussion of the proposal in this list thread: https://lists.w3.org/Archives/Public/public-houdini/2015Jan/0005.html
Not sure if it is going to be a future CSS standard. But you can already do it with SASS and SCSS. Here is SCSS syntax:
.myClass {
color: blue;
}
h1 {
#extend .myClass;
...
}
Documentation: https://sass-lang.com/documentation/at-rules/extend
Well, in effect what you are trying to do is to make your CSS properties defined in the .myClass block, apply in your h1 block, (correct me if I'm wrong).
If that's what you meant, you can already do that by simply adding myClass to your h1 tag like <h1 class="myClass">Header</h1> and in your CSS you would do this:
.myClass {
color: blue;
}
// or
h1.myClass {
color: blue; // To only target h1 that have the 'myClass' class
}
Will future CSS standard allow applying classes to elements in a style declaration?
Well as you can see we can already do that with HTML, so I doubt it.

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; }
}

Updating a Variable through a Mixin

So lets say I set the background of 10 elements on the page to #base, then a user lands on the "Foo" page which has the class on the body of the page.
How does one update the #base via a css declaration? I understand that variables are local to a function (or css declaration) but there must be a method to do this! (would make styling alternative pages so easy!)
#base: #00000;
body.foo{
#base = #FFF;
}
LESS is a Preprocessor so...
...it all has to be precompiled into CSS ahead of time. That means all possible class combinations need to be made into valid CSS ahead of time. If you wanted something like this, you would need to do something like the following in your LESS:
LESS
#base: #000000;
.setColorOptions(#className: ~'', #base: #base) {
#classDot: escape(`('#{className}' == '' ? '' : '.')`);
#class: escape(#className);
body#{classDot}#{class} {
someElement {color: #base;}
.someClass {color: #base;}
// etc.
}
}
.setColorOptions();
.setColorOptions(foo, #fff);
.setColorOptions(bar, #ccc);
CSS Output
body someElement {
color: #000000;
}
body .someClass {
color: #000000;
}
body.foo someElement {
color: #ffffff;
}
body.foo .someClass {
color: #ffffff;
}
body.bar someElement {
color: #cccccc;
}
body.bar .someClass {
color: #cccccc;
}
Obviously if there were many elements and a lot of color dependent things going on, this could get big fast. Imagine 100 elements under body with three color variations as above, and you have 300+ lines of CSS, 200+ (two-thirds) of which do not apply to any one page. And this doesn't account for other changes, like background colors, etc. In such a case, it is best to set up different LESS files that import a different set of values for #base and build different style sheets to be loaded on the pages that need it. However, if you are just doing a small subset of color changes to a page, this could be a valid way to go.
There is no way to do that.
LESS has no way to know whether the selector body.foo will apply at compile time.

CSS - Match a whole attribute value

HTML
<div data-whatever='something cols-16 else'>
</div>
This works:
Will work - CSS
[data-whatever*='cols-1'] {
background: red;
}
It will find the div and make it red.
Will not work - CSS
[data-whatever='cols-16'] {
background: red;
}
It will not find the div because there are other stuff in there as well.
Problem
The problem with the working CSS, is that it matches both cols-16, cols-1 and any other that starts with cols-1.
Question
Is it possible to find an attribute value, exact match?
In order to target the class cols-16 (even when it appears with other classes)
and not target the cols-1 class use this:
[data-whatever~='cols-16'] {
background: green;
}
You can see this working in this fiddle.
For more info see this post (Goto #16. - X[foo~="bar"]
The tilda (~) symbol allows us to target an attribute which has a
spaced-separated list of values.
try this:
[data-whatever~='cols-1'] {
background: red;
}
It worked for me if I didn't missunderstand your question
Edit: I just remembered the ~= randomly, tried it, and pasted it.
But I just googled a bit (I had curiosity and found This, it's quite interesting)
To ensure that it only matches cols-1 and not cols-16 without relying on the cols-16 style overriding the cols-1 style (below), you could:
[data-whatever='cols-1'],
[data-whatever^='cols-1 '],
[data-whatever*='cols-1 '],
[data-whatever$='cols-1'] {
background: red;
}
This matches data-whatever="cols-1", data-whatever="... cols-1", data-whatever="cols-1 ..." or data-whatever="... cols-1 ...".
JSFiddle example.
Thanks to aleation's answer: data-whatever~="cols-1" achieves the same as the above in just one selector.
--
At any rate your cols-16 styling could overwrite your cols-1 styling anyway, depending on the order it was presented:
[data-whatever*='cols-1'] {
background: red;
}
[data-whatever*='cols-16'] {
background: blue;
}
/* cols-1 will be red. cols-16 will be blue */
JSFiddle example.

CSS "properties of .x" syntax

Is it possible to add additional rules to a css block when using a "{ (properties of x) }" selector?
I looked at references but I can't find anything related to "properties of x". A link would be wonderful. I tried the following two combinations, but neither worked:
.dock li { (properties of grid_2; display:inline; background-color:#666; ) }
.dock li { display:inline; background-color:#666; (properties of grid_2) }
Many thanks!
EDIT
Apparently I misread an article and thought that such a syntax existed. I thought one could create a class and let it inherit the properties of another using such syntax, which is evidently not the case.
CSS does not have such a feature.
What you are describing is not possible. I think there are two other possibilities you could maybe use. The first is, that you need to know that several styles can be applied to an element at the same time. I'll give you an example:
li { font-size: 10pt; }
.dock li { color: #ff0000; }
All list items will be formatted with a font size of 10 points and only those within an element containing the dock class will be red.
My second suggestion is that you try applying two or more classes to your HTML element, for instance:
.grid li { font-size: 10pt; }
.dock li { color: #ff0000; }
Now put the grid and dock class into your HTML, and the elements will apply both style definitions:
<ul class="grid dock"> ...
Whatever you consider best for your project: remember that the properties defined in the second style overwrite the properties of the first one (if they do not define the same properties at all, there will be no confusion).
maybe your question is not too strange..
What I understand is that you want to do something like:
.a { prop1: val; prop2: val; }
.b { prop3: val; prop4: val; }
.c { .a; .b; prop5: val; prop6: val; }
You want the class .c to inherit all the properties and values of .a and .b
If this is ok, you can do that using LESS.
To use your LESS code in your sites you have different ways to do it.
First of all check the original site: LESS.org
If you are on Mac check this site: LESS APP + PLUGINS
If you are on PC the less.js plugin should be easier to implement LESS in your sites: less.js usage
Hope it helps.
Happy coding y'all! :)

Resources