Related
The following is meant to toggle stylesheets:
body.light {
background: var(--bg);
color: var(--text);
& a {
color: var(--link_color);
}
}
body.dark {
color: var(--bg);
background: var(--text);
& a {
color: white;
}
}
This snippet is in the last loaded file, amongst a few CSS files.
Problem: while the attributes are executed properly, the nesting for the selectors is not being picked up (It was expected the ampersand was the proper way to go).
There is a framework CSS file (loaded before the file where this code is placed) and it is those attributes that are executed.
What are the syntactic requirements to run properly nested selectors (be they native tag selectors (such as `a) or user-defined selectors?
update
The theme is being generated via a cookies[:theme]
and the body tag adopts it this way:
<body class="<%= cookies[:theme] %>">
To make it work in regular CSS, rewrite without use of &.
Exmaple:
body.light {
background: var(--bg);
color: var(--text);
}
body.light a {
color: var(--link_color);
}
body.dark {
color: var(--bg);
background: var(--text);
}
body.dark a {
color: white;
}
Regarding the ampersand, according to Sass document:
The parent selector, &, is a special selector invented by Sass that’s used in nested selectors to refer to the outer selector. It makes it possible to re-use the outer selector in more complex ways, like adding a pseudo-class or adding a selector before the parent.
Currently, usage of & will require a css preprocessor like Sass, and also the & is widely adopted by many syntax such as Sass, SCSS, Less.
CSS nesting is not possible with standard CSS but only with CSS preprocessors like Sass and Less.
Caniuse.com says
CSS nesting provides the ability to nest one style rule inside another, with the selector of the child rule relative to the selector of the parent rule. Similar behavior previously required a CSS pre-processor.
but the page does not shows any supported browser.
There are some more information on developer.chrome.com. The examples use the > character.
This is because, you used Sass in your project. Sass is a preprocessor scripting language that compiled into CSS. Sass reduces repetition of CSS and therefore saves time.
Let say you have this kind of HTML.
<div class="parent">
parent
<div class="child">
child
<div class="container desc">container</div>
</div>
</div>
assume you need these requirements, you need to make container class to add background to green. and desc class to width 500px.
you can do this by,
.parent {
.container {
background: green;
&.desc {
width: 500px;
}
}
}
One Note, In order to use Sass, you have to enable it from your project.If you use Angular,Vue or React, use
npm i sass
I hope this make sense to you.
I have created a custom style sheet that overrides the original CSS for my Wordpress template. However, on my calendar page, the original CSS has the height of each table cell set with the !important declaration:
td {height: 100px !important}
Is there some way I can override this?
Overriding the !important modifier
Simply add another CSS rule with !important, and give the selector a higher specificity (adding an additional tag, id or class to the selector)
add a CSS rule with the same selector at a later point than the existing one (in a tie, the last one defined wins).
Some examples with a higher specificity (first is highest/overrides, third is lowest):
table td {height: 50px !important;}
.myTable td {height: 50px !important;}
#myTable td {height: 50px !important;}
Or add the same selector after the existing one:
td {height: 50px !important;}
Disclaimer:
It's almost never a good idea to use !important. This is bad engineering by the creators of the WordPress template. In viral fashion, it forces users of the template to add their own !important modifiers to override it, and it limits the options for overriding it via JavaScript.
But, it's useful to know how to override it, if you sometimes have to.
Apart from overriding a style set by the style attribute, the !important should only be used when you have selectors in your style sheet with conflicting specificity.
But even when you have conflicting specificity, it is better to create a more specific selector for the exception. In your case it's better to have a class in your HTML which you can use to create a more specific selector which doesn't need the !important rule.
td.a-semantic-class-name { height: 100px; }
I personally never use !important in my style sheets. Remember that the C in CSS is for cascading. Using !important will break this.
Disclaimer: Avoid !important at all cost.
This is a dirty, dirty hack, but you can override an !important, without an !important, by using an (infinitely looping or very long lasting) animation on the property you're trying to override the importants on.
#keyframes forceYellow {
from {
background-color: yellow;
}
to {
background-color: yellow;
}
}
div {
width: 100px;
height: 100px;
margin: 0 auto;
background: red !important;
animation: 1s linear infinite forceYellow;
}
<div></div>
Every part of the styles name has a weight, so the more elements you have that relate to that style the more important it is. For example
#P1 .Page {height:100px;}
is more important than:
.Page {height:100px;}
So when using important, ideally this should only ever be used, when really really needed. So to override the declaration, make the style more specific, but also with an override. See below:
td {width:100px !important;}
table tr td .override {width:150px !important;}
Override using JavaScript
$('.mytable td').attr('style', 'display: none !important');
Worked for me.
This can help too
td[style] {height: 50px !important;}
This will override any inline style
In any case, you can override height with max-height.
You can use higher specificity by going up in selectors.
td {height: 100px !important}
/* higher precedence */
table td {height: 200px !important}
I wrote a detailed article on how to override CSS here.
I found really cool trick with :not.
If nothing from above helped you, then try this:
.page-width:not(.anything) {
}
If you're trying to override an !important tag that is defined in a class. Simply specify your property in a id tag. id has higher precedence than class.
There are a couple of modern approaches that weren't available when this question was first asked.
Use :is() to set an arbitrarily high specificity to your selector
:is(td, #A#A#A:not(*)) {height: 200px !important}
The second parameter to the :is() sets the specificity of the whole selector but the :not(*) part means that the parameter will never match any element itself. #A#A#A gives a specificity of (3,0,0) but you can safely choose whatever selector is sufficient to override the other !important setting. However, this is still something of a hack.
A better way is to use cascade layers. Layered !important declarations override non-layered !important declarations so you can just do:
#layer {
td {height: 200px !important}
}
By using named layers you can further override this to arbitrary levels.
Note that neither approach will allow you to override a !important setting in an HTML style attribute.
I would like to add an answer to this that hasn't been mentioned, as I have tried all of the above to no avail. My specific situation is that I am using semantic-ui, which has built in !important attributes on elements (extremely annoying). I tried everything to override it, only in the end did one thing work (using jquery). It is as follows:
$('.active').css('cssText', 'border-radius: 0px !important');
The page I am working on has many different CSS files attached to it, a boostrap.css, the master.css and a custom.css file.
I'm trying to remove a property, as I don't want there to be a a:hover property on the link in a menu. The master CSS file has
#topSurround a:hover {
color: #ffffff;
}
The bootstrap CSS file has
.nav > li > a:hover {
text-decoration: none;
background-color: #eee;
}
I don't want to edit these files, as they are core files with the template I am using and could be updated, so I am using a custom CSS file. Normally, I would set the property to default to override any previous uses of the property.
#topSurround a:hover {
color: none; (doesn't work, as this isn't the correct default)
}
So, two questions: What is the default value for the color property (there doesn't seem to be one)? Is there an easier way to go about this without having to overwrite the core files?
You can use color: inherit to have the color use the value from its ancestors. color is odd in that it has different default values depending on context. A link, for example, will typically default to blue, while text will default to black.
If you need to override the existing style, don't use a more specific selector. Raising the specificity means that you'll just have to use more selectors the next time you want to override it.
Instead, take advantage of the cascade by using a selector with identical specificity and make the override happen after the original style:
/* older style in some library */
.foo .bar .baz {
color: blue;
}
...in an overriding CSS file...
.foo .bar .baz {
color: green;
}
To cancel out the property you can use unset keyword.
So, in you custom css file you can do something like following:-
#topSurround a:hover {
color: unset;
}
According to the MDN Web Docs:-
The unset CSS keyword resets a property to its inherited value if it inherits from its parent, and to its initial value if not. In other words, it behaves like the inherit keyword in the first case, and like the initial keyword in the second case. It can be applied to any CSS property, including the CSS shorthand all.
The best way is to make a more specific CSS rule, such as:
body #topSurround a:hover {
color: transparent;
}
Specificity is an important CSS concept, as described in this article:
http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/
I'd recommend trying:
#topSurround a:hover {
color: inherit;
}
As for how to overwrite what Bootstrap is adding, I think how you were doing it is best.
Every CSS style has a natural default value. It's just not always none.
Some may be 0 (as in zero).
Some may be auto.
Sometimes inherit is the best option.
Colours can be set to transparent.
If you're unsure what the default is, try creating a dummy page with just a plain unstyled element, and use the browser dev tools to see what the styles are set to.
I have created a custom style sheet that overrides the original CSS for my Wordpress template. However, on my calendar page, the original CSS has the height of each table cell set with the !important declaration:
td {height: 100px !important}
Is there some way I can override this?
Overriding the !important modifier
Simply add another CSS rule with !important, and give the selector a higher specificity (adding an additional tag, id or class to the selector)
add a CSS rule with the same selector at a later point than the existing one (in a tie, the last one defined wins).
Some examples with a higher specificity (first is highest/overrides, third is lowest):
table td {height: 50px !important;}
.myTable td {height: 50px !important;}
#myTable td {height: 50px !important;}
Or add the same selector after the existing one:
td {height: 50px !important;}
Disclaimer:
It's almost never a good idea to use !important. This is bad engineering by the creators of the WordPress template. In viral fashion, it forces users of the template to add their own !important modifiers to override it, and it limits the options for overriding it via JavaScript.
But, it's useful to know how to override it, if you sometimes have to.
Apart from overriding a style set by the style attribute, the !important should only be used when you have selectors in your style sheet with conflicting specificity.
But even when you have conflicting specificity, it is better to create a more specific selector for the exception. In your case it's better to have a class in your HTML which you can use to create a more specific selector which doesn't need the !important rule.
td.a-semantic-class-name { height: 100px; }
I personally never use !important in my style sheets. Remember that the C in CSS is for cascading. Using !important will break this.
Disclaimer: Avoid !important at all cost.
This is a dirty, dirty hack, but you can override an !important, without an !important, by using an (infinitely looping or very long lasting) animation on the property you're trying to override the importants on.
#keyframes forceYellow {
from {
background-color: yellow;
}
to {
background-color: yellow;
}
}
div {
width: 100px;
height: 100px;
margin: 0 auto;
background: red !important;
animation: 1s linear infinite forceYellow;
}
<div></div>
Every part of the styles name has a weight, so the more elements you have that relate to that style the more important it is. For example
#P1 .Page {height:100px;}
is more important than:
.Page {height:100px;}
So when using important, ideally this should only ever be used, when really really needed. So to override the declaration, make the style more specific, but also with an override. See below:
td {width:100px !important;}
table tr td .override {width:150px !important;}
Override using JavaScript
$('.mytable td').attr('style', 'display: none !important');
Worked for me.
This can help too
td[style] {height: 50px !important;}
This will override any inline style
In any case, you can override height with max-height.
You can use higher specificity by going up in selectors.
td {height: 100px !important}
/* higher precedence */
table td {height: 200px !important}
I wrote a detailed article on how to override CSS here.
I found really cool trick with :not.
If nothing from above helped you, then try this:
.page-width:not(.anything) {
}
There are a couple of modern approaches that weren't available when this question was first asked.
Use :is() to set an arbitrarily high specificity to your selector
:is(td, #A#A#A:not(*)) {height: 200px !important}
The second parameter to the :is() sets the specificity of the whole selector but the :not(*) part means that the parameter will never match any element itself. #A#A#A gives a specificity of (3,0,0) but you can safely choose whatever selector is sufficient to override the other !important setting. However, this is still something of a hack.
A better way is to use cascade layers. Layered !important declarations override non-layered !important declarations so you can just do:
#layer {
td {height: 200px !important}
}
By using named layers you can further override this to arbitrary levels.
Note that neither approach will allow you to override a !important setting in an HTML style attribute.
If you're trying to override an !important tag that is defined in a class. Simply specify your property in a id tag. id has higher precedence than class.
I would like to add an answer to this that hasn't been mentioned, as I have tried all of the above to no avail. My specific situation is that I am using semantic-ui, which has built in !important attributes on elements (extremely annoying). I tried everything to override it, only in the end did one thing work (using jquery). It is as follows:
$('.active').css('cssText', 'border-radius: 0px !important');
Is there a way to import the styling of a single CSS selector into another CSS selector and add to it or rewrite properties from it.
Let's say:
.original_class{
background:black;
color:white;
}
.overwrite{
#import(.original_class); /* I know this doesn't work */
color:blue;
border:1px solid green;
}
I can accomplish this by just redeclaring the .original_class and assigning new values (since CSS styles are rewritten from top to bottom), but this will replace the attributes of the original CSS class. What I want is to inherit its properties into another class without having to write them again (duplicate).
Not directly, no.
You could do something like this in your HTML:
<div class="original_class overwrite">...</div>
This will have the same effect, but you will have to do this for every element you want styled that way.
There is also the option of using a CSS pre-processor, like SASS, which supports inheritance/mixins.
You can add the .overwrite selector to the first rule by separating it from the existing selector with a comma (grouping selectors), so the selector rule becomes .original_class, .overwrite:
.original_class,
.overwrite {
background: black;
color: white;
}
.overwrite {
color: blue;
border: 1px solid green;
}
Also, when you write:
this will replace the attributes of the original CSS class
there is no such thing as attributes and class in CSS, not with the intended meaning of OOP I guess. There are rules, selector rules (to select HTML id, classes, elements, attributes and other pseudos), declarations, properties and values.
Unfortunately not. At least not without one of those fancy CSS plugin thingies that I wouldn't touch with a mile-long pole...
Of course, there's nothing stopping you having multiple classes on a single element.