I have created a few classes in my javascript file that will be essentially referenced in the CSS file as "tr.Yes" "tr.No" and the new one "tr.override".
I want to override the values of tr.Yes and tr.No with tr.override due to a few added constraints in the JS file. Basically, how would I override them with tr.override that has a background of green?
Thanks guys.
My CSS so far looks as follows:
tr.Yes td.IndicatedDispatch {
background: yellow;
}
tr.No td.IndicatedDispatch {
background: red;
}
If you want the override class to override the yes and no classes define your overrideclass after the other ones in your CSS file and redefine the same rules with different values.
Like this
tr.Yes td.IndicatedDispatch {
background: red;
}
tr.Override td.IndicatedDispatch {
background: green; /* Redefine here*/
}
You can override CSS declarations by making them more specific. Go higher up the DOM.
tr.Yes td.IndicatedDispatch {
background: yellow;
}
becomes:
table tr.Yes td.IndicatedDispatch {
background: red;
}
Related article: http://www.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/
If you're going to add the override class and leave the original classes, you create a combination rule like this:
tr.Yes td.IndicatedDispatch {
background: yellow;
}
tr.No td.IndicatedDispatch {
background: red;
}
tr.Yes.override td.IndicatedDispatch ,
tr.No.override td.IndicatedDispatch {
background: green;
}
CSS works from top to bottom, i.e selector1 css attributes will be overridden by selector1 css attributes defined at last(MORE SPECIFIC). For example
.myClass{
color: #000000;
}
/*
* Some other code
*
*/
.myClass{
color: #FFFFFF;
}
So at run time color:#FFF color will be picked up.
You could change your selectors to tr.Yes:not(.override) so that they do not take effect when the override class is in effect. Otherwise, both the tr.Yes and the tr.override styling will be merged, and anything from tr.Yes that is not overridden by tr.override will remain.
Related
A WebComponent may include CSS Custom Properties in its encapsulated styles.
This gives consumers of the component a way to customise that component's styles:
See: Creating style hooks using CSS custom properties | Google Web Fundamentals
Declaring
--fancy-tabs-bg: red
in the main styles means that when the shadow-root styles include
background-color: var(--fancy-tabs-bg, #9E9E9E)
the background-color will be red (or whatever value --fancy-tabs-bg is set to).
But... I note in the same article it explicitly states:
One gotcha with :host is that rules in the parent page have higher
specificity than :host rules defined in the element. That is,
outside styles win. This allows users to override your top-level
styling from the outside.
and again, later:
Outside styles always win over styles defined in shadow DOM. For example, if the user writes the selector fancy-tabs { width: 500px; }, it will trump the component's rule: :host { width: 650px;}
So... instead of declaring a value for --fancy-tabs-bg we could just... set a value for background-color (?)
Really? Let's find out.
Here's a WebComponent (largely copied from the article referenced above) where the first two instances of the component are styled using a CSS Custom Property (ie. --fancy-tabs-bg) and the third instance is styled directly, using the relevant CSS Property (ie. background-color).
class FancyTabs extends HTMLElement {
constructor() {
super();
this.root = this.attachShadow({mode: "open"});
}
connectedCallback() {
this.root.innerHTML = `
<style>
:host {
display: block;
width: 100px;
height: 100px;
margin: 6px;
border-radius: 10px;
}
:host([background]) {
background-color: var(--fancy-tabs-bg, #9E9E9E);
}
</style>
`;
}
}
customElements.define('fancy-tabs', FancyTabs);
fancy-tabs {
float: left;
}
fancy-tabs:nth-of-type(1) {
--fancy-tabs-bg: red;
}
fancy-tabs:nth-of-type(2) {
--fancy-tabs-bg: orange;
}
fancy-tabs:nth-of-type(3) {
background-color: green;
}
<fancy-tabs background>...</fancy-tabs>
<fancy-tabs background>...</fancy-tabs>
<fancy-tabs background>...</fancy-tabs>
There's no difference, is there?
So why use CSS Custom Properties at all? Why highlight in the public interface that a particular CSS property is available for user-customisation? Surely all CSS properties are available for user-customisation, aren't they?
What am I missing?
You won't notice any difference when dealing with the host element but you can clearly see the use of CSS variables when having more elements inside:
Example where CSS variables is useful to update the styling of nested elements. I doubt you can find a better way without CSS variables.
class FancyTabs extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'closed' });
const css = `
:host {
display: block;
width: 100px;
height: 100px;
margin: 6px;
border-radius: 10px;
}
:host([background]) {
background-color: var(--fancy-tabs-bg, #9E9E9E);
}
div {
padding: var(--p,0px);
border:var(--b,0px) solid;
}`
this.styles = document.createElement('style');
this.styles.innerHTML = css;
}
connectedCallback() {
const div = document.createElement('div');
div.innerHTML = this.innerHTML;
this.shadow.appendChild(this.styles);
this.shadow.appendChild(div);
}
}
customElements.define('fancy-tabs', FancyTabs);
fancy-tabs {
float: left;
}
fancy-tabs:nth-of-type(1) {
--fancy-tabs-bg: red;
--p:20px;
--b:5px;
}
fancy-tabs:nth-of-type(2) {
--fancy-tabs-bg: orange;
--p:10px;
--b:3px;
}
fancy-tabs:nth-of-type(3) {
--fancy-tabs-bg: orange;
padding:20px; /* will get applied to host*/
border-width:5px; /* will do nothing */
}
<fancy-tabs background>text here</fancy-tabs>
<fancy-tabs background>text here</fancy-tabs>
<fancy-tabs background>text here</fancy-tabs>
In the example below, I want to change pad's color via JS to green, but also make it transition to yellow when it is active.
However, changing the color via JS like this: pad.style.background = 'green' will make the transition stop working. If I remove this line, the transition will work fine.
Why is that so and how can I fix this?
let pad = document.getElementsByClassName('pad')[0]
pad.style.background = 'green'
.pad{
width: 80px;
height: 80px;
background: black;
transition: background .5s;
}
.pad:active {
background: yellow;
}
<!DOCTYPE HTML>
<body>
<div class="pad"></div>
</body>
The reason for not working is because pad.style.background will add an inline css style which has a priority over a css class
Solution:
use a class instead of inline style like in the code bellow:
let pad = document.getElementsByClassName('pad')[0]
pad.classList.add("green");
.pad {
width: 80px;
height: 80px;
background: black;
transition: background .5s;
}
.pad.green {
background: green;
}
.pad:active {
background: yellow;
}
<div class="pad"></div>
It seems like JS is adding green to the :active state too.
Add !important to the active style in your css to make it more of a priority:
.pad:active {
background: yellow!important;
}
This is happening because you're overriding the existing style by applying the style via style attribute on the HTML element.
Instead you should create a new class and apply that using JavaScript, in that case the original styles won't be overidden and the transition would still work
Have your CSS as:
.pad {
width: 80px;
height: 80px;
background: black;
transition: background .5s;
}
.pad:active {
background: yellow;
}
.pad-green {
background: green;
}
And then in your JavaScript, do this:
let pad = document.getElementsByClassName('pad')[0]
pad.classList.add('pad-green')
Hope that helps, let me know in the comments if there are any questions.
I'm in desperate need of scoping my css to a specific div.
What I want, is for my styles within a certain div to only affect anything within that div, and nothing outside it.
Example:
<style>
p {
color: red;
}
</style>
<div class="global">
<p>I am styled by the global styling!</p>
</div>
<div class="scoped">
<style>
p{
color: blue;
background: green;
}
</style>
<p>These scoped styles do not affect the global styles</p>
</div>
I know about placing scoped on the style tag, but the browser support is no where near close to practical use.
Because of that, I'm wondering if there is some way to achieve this by other means, like JavaScript?
Thanks!
EDIT:
I'm not in search for scoping it by placing a class before it, like .scoped p.
I need it to be dynamic, and i can't place .scoped in front of all the tags.
How about using CSS classes? For example:
/* This only applies to p inside div with class 'global' */
div.global p {
color: red;
}
/* This only applies to p inside div with class 'scoped' */
div.scoped p{
color: blue;
background: green;
}
If you want all p to have global style and only scoped to have separate style, leave the p rule as it is and create scoped rule:
/* This rule applies to all p elements */
p {
color: red;
}
/* This style overrides style of p inside div with class 'scoped' */
div.scoped p{
color: blue;
background: green;
}
select every class separately:
.global p {
color: red;
}
.scoped p{
color: blue;
background: green;
}
I want to use the :fullscreen css pseudo-class which requires a number of vendor pre-fixes:
html:fullscreen {
background: red;
}
html:-moz-full-screen {
background: red;
}
html:-webkit-full-screen {
background: red;
}
html:-ms-fullscreen {
background: red;
width: 100%; /* needed to center contents in IE */
}
But for this example I would prefer not to have to duplicate background:red and all other css across the 4 prefixes. If I do the following it appears as though the browser ignores it (which I believe is due to how the accepts css):
html:fullscreen,
html:-moz-full-screen,
html:-webkit-full-screen,
html:-ms-fullscreen
{
background: red;
}
Is there any pure css way to make this work? If not what is the best way?
Unfortunately it seems you have to repeat those declaration. Look at sitepoint article - http://www.sitepoint.com/html5-full-screen-api/
Take a look at the -prefix-free thing.
I am not going to mark this the correct solution since it's not pure css, but my solution was to use less (Sass/Scss would also work) and implement a mixin:
.fullscreenMixin {
font-weight: normal;
font-size: 49px;
}
html:fullscreen {
.fullscreenMixin()
background: red;
}
html:-moz-full-screen {
.fullscreenMixin()
}
html:-webkit-full-screen {
.fullscreenMixin()
}
html:-ms-fullscreen {
.fullscreenMixin()
width: 100%; /* needed to center contents in IE */
}
I want that some of my jquery dialogs, not all, have a different title bar color.
How can I acheive this?
I used the property dialogClass:"myClass" in desired dialogs but this doesen't change the title bar, just the dialog body.
Thank you!!
Specifying a dialogClass adds this class to the outermost div wrapping the entire dialog including the title bar, so you just have to make sure that you CSS rule is targeting the correct element. For instance:
.myDialogClass .ui-widget-header {
background: purple;
}
div.ui-widget-header {
border: 1px solid #3b678e;
background: #3b678e url("images/ui-bg_gloss-wave_35_3b678e_500x100.png") 50% 50% repeat-x;
color: #ffffff;
font-weight: bold;
}
You could do:
div#myDialog .ui-dialog-titlebar {
background-color: red;
}
The .ui-dialog-titlebar is what you are looking to apply your style to.