Applying CSS Styling to Child Based on Ancestor Class - javascript

OK - I have a pretty basic page that I'm trying to keep as simple as possible. I have a "theme selector" that chooses between a light and dark theme, and sets the body's class based on that, basically changing from white/black background/text. I have boxes within that are a different background color that also need to change... is there a way to change the applied class of a child (perhaps many removed) based on the class of the body tag (or any ancestor for that matter) using CSS?
Simple demo:
<body class="dark">
<div class="container">
<div class="differentBG">THIS IS THE BOX I WANT TO CHANGE!</div>
</div>
</body>
I know I can use js (d3 is what I'm using) to apply a class to all of the children, but I want to keep as much in CSS as possible...

You can base rules off of ancestor classes on the body tag as you would any other tag in your markup:
body.dark .differentBG {
background: black;
color: white;
}
Our differentBG class will apply a black background only when the <body> has a class of "dark".
body.light .differentBG {
background: white;
color: black
}
Our differentBG class will apply a white background when <body> has a class of "light".
As an added bit of trivia, many developers use this very technique to setup their "JavaScript Disabled" styles:
body.nojs .dynamicElement {
display: none;
}
And then use JavaScript to remove that class when the page loads. Modernizr also uses this method, though it adds classes to the <html> element to indicate what features the user agent supports.

Related

How to use the pseudo selectors in Inline Css in material UI? [duplicate]

I have a case where I must write inline CSS code, and I want to apply a hover style on an anchor.
How can I use a:hover in inline CSS inside the HTML style attribute?
E.g., you can't reliably use CSS classes in HTML emails.
Short answer: you can't.
Long answer: you shouldn't.
Give it a class name or an id and use stylesheets to apply the style.
:hover is a pseudo-selector and, for CSS, only has meaning within the style sheet. There isn't any inline-style equivalent (as it isn't defining the selection criteria).
Response to the OP's comments:
See Totally Pwn CSS with Javascript for a good script on adding CSS rules dynamically. Also see Change style sheet for some of the theory on the subject.
Also, don't forget, you can add links to external stylesheets if that's an option. For example,
<script type="text/javascript">
var link = document.createElement("link");
link.setAttribute("rel","stylesheet");
link.setAttribute("href","http://wherever.com/yourstylesheet.css");
var head = document.getElementsByTagName("head")[0];
head.appendChild(link);
</script>
Caution: the above assumes there is a head section.
You can get the same effect by changing your styles with JavaScript in the onMouseOver and onMouseOut parameters, although it's extremely inefficient if you need to change more than one element:
<a href="abc.html"
onMouseOver="this.style.color='#0F0'"
onMouseOut="this.style.color='#00F'" >Text</a>
Also, I can't remember for sure if this works in this context. You may have to switch it with document.getElementById('idForLink').
You could do it at some point in the past. But now (according to the latest revision of the same standard, which is Candidate Recommendation) you can't
.
You can't do exactly what you're describing, since a:hover is part of the selector, not the CSS rules. A stylesheet has two components:
selector {rules}
Inline styles only have rules; the selector is implicit to be the current element.
The selector is an expressive language that describes a set of criteria to match elements in an XML-like document.
However, you can get close, because a style set can technically go almost anywhere:
<html>
<style>
#uniqueid:hover {do:something;}
</style>
<a id="uniqueid">hello</a>
</html>
If you actually require inline code, this is possible to do. I needed it for some hover buttons, and the method is this:
.hover-item {
background-color: #FFF;
}
.hover-item:hover {
background-color: inherit;
}
<a style="background-color: red;">
<div class="hover-item">
Content
</div>
</a
In this case, the inline code: "background-color: red;" is the switch colour on hover. Use the colour you need and then this solution works. I realise this may not be the perfect solution in terms of compatibility, however this works if it is absolutely needed.
While it appears to be impossible to define a hover-rule inline, you can define the value of styles inline using a CSS variable:
:hover {
color: var(--hover-color);
}
<a style="--hover-color: green">
Library
</a>
Consider using an attribute or a class in addition to the selector (e.g., [hover-color]:hover) to allow coexistence with other low specificity hover color changing rules (from, e.g., a CSS reset or some elements using the default style).
Using JavaScript:
a) Adding inline style
document.head.insertAdjacentHTML('beforeend', '<style>#mydiv:hover{color:red;}</style>');
b) or a bit harder method - adding "mouseover"
document.getElementById("mydiv").onmouseover= function(e){this.className += ' my-special-class'; };
document.getElementById("mydiv").onmouseleave= function(e){this.className = this.className.replace('my-special-class',''); };
Note: multi-word styles (i.e.font-size) in JavaScript are written together:
element.style.fontSize="12px"
This is the best code example:
<a
style="color:blue;text-decoration: underline;background: white;"
href="http://aashwin.com/index.php/education/library/"
onmouseover="this.style.color='#0F0'"
onmouseout="this.style.color='#00F'">
Library
</a>
Moderator Suggestion: Keep your separation of concerns.
HTML
<a
style="color:blue;text-decoration: underline;background: white;"
href="http://aashwin.com/index.php/education/library/"
class="lib-link">
Library
</a>
JS
const libLink = document.getElementsByClassName("lib-link")[0];
// The array 0 assumes there is only one of these links,
// you would have to loop or use event delegation for multiples
// but we won't go into that here
libLink.onmouseover = function () {
this.style.color='#0F0'
}
libLink.onmouseout = function () {
this.style.color='#00F'
}
Inline pseudoclass declarations aren't supported in the current iteration of CSS (though, from what I understand, it may come in a future version).
For now, your best bet is probably to just define a style block directly above the link you want to style:
<style type="text/css">
.myLinkClass:hover {text-decoration:underline;}
</style>
Foo!
As pointed out, you cannot set arbitrary inline styles for hover, but you can change the style of the hover cursor in CSS using the following in the appropriate tag:
style="cursor: pointer;"
<style>a:hover { }</style>
Go Home
Hover is a pseudo class, and thus cannot be applied with a style attribute. It is part of the selector.
You can do this. But not in inline styles. You can use onmouseover and onmouseout events:
<div style="background: #333; padding: 10px; cursor: pointer"
onmouseover="this.style.backgroundColor='#555';" onmouseout="this.style.backgroundColor='#333';">
Hover on me!
</div>
According to your comments, you're sending a JavaScript file anyway. Do the rollover in JavaScript. jQuery's $.hover() method makes it easy, as does every other JavaScript wrapper. It's not too hard in straight JavaScript either.
There is no way to do this. Your options are to use a JavaScript or a CSS block.
Maybe there is some JavaScript library that will convert a proprietary style attribute to a style block. But then the code will not be standard-compliant.
You can write code in various type.
First I can write this
HTML
<a href="https://www.google.com/" onMouseOver="this.style.color='red'"
onMouseOut="this.style.color='blue'" class="one">Hello siraj</a>
CSS
.one {
text-decoration: none;
}
You can try another way:
HTML
Hello siraj
CSS
.one {
text-decoration: none;
}
.one:hover {
color: blue;
}
.one:active {
color: red;
}
You can also try hover in jQuery:
JavaScript
$(document).ready(function() {
$("p").hover(function() {
$(this).css("background-color", "yellow");
}, function() {
$(this).css("background-color", "pink");
});
});
HTML
<p>Hover the mouse pointer over this paragraph.</p>
In this code you have three functions in jQuery. First you ready a function which is the basic of a function of jQuery. Then secondly, you have a hover function in this function. When you hover a pointer to the text, the color will be changed and then next when you release the pointer to the text, it will be the different color, and this is the third function.
I just figured out a different solution.
My issue: I have an <a> tag around some slides/main content viewer as well as <a> tags in the footer. I want them to go to the same place in IE, so the whole paragraph would be underlined onHover, even though they're not links: the slide as a whole is a link. IE doesn't know the difference. I also have some actual links in my footer that do need the underline and color change onHover. I thought I would have to put styles inline with the footer tags to make the color change, but advice from above suggests that this is impossible.
Solution: I gave the footer links two different classes, and my problem was solved. I was able to have the onHover color change in one class, have the slides onHover have no color change/underline, and still able to have the external HREFS in the footer and the slides at the same time!
It's not exactly inline CSS, but it is inline.
<a href="abc.html" onMouseOver="this.style.color='#0F0'"
onMouseOut="this.style.color='#00F'">Text</a>
I agree with shadow. You could use the onmouseover and onmouseout event to change the CSS via JavaScript.
And don't say people need to have JavaScript activated. It's only a style issue, so it doesn't matter if there are some visitors without JavaScript ;)
Although most of Web 2.0 works with JavaScript. See Facebook for example (lots of JavaScript) or Myspace.
So this isn't quite what the user was looking for, but I found this question searching for an answer and came up with something sort of related. I had a bunch of repeating elements that needed a new color/hover for a tab within them. I use handlebars, which is key to my solution, but other templateing languages may also work.
I defined some colors and passed them into the handlebars template for each element. At the top of the template I defined a style tag, and put in my custom class and hover color.
<style type="text/css">
.{{chart.type}}-tab-hover:hover {
background-color: {{chart.chartPrimaryHighlight}} !important;
}
</style>
Then I used the style in the template:
<span class="financial-aid-details-header-text {{chart.type}}-tab-hover">
Payouts
</span>
You may not need the !important
While the "you shouldn't" context may apply there may be cases were you still want to achieve this. My use case was to dynamic set a hover color depending on some data value to achieve that with only CSS you can benefit from specificity.
Approach CSS only
CSS
/* Set your parent color for the inherit property */
.sidebar {
color: green;
}
/* Make sure your target element "inherit" parent color on :hover and default */
.list-item a {
color: inherit
}
.list-item a:hover {
color: inherit
}
/* Create a class to allows to get hover color from inline style */
.dynamic-hover-color:not(:hover) {
color: inherit !important;
}
Then your markup will be somewhat like:
Markup
<nav class="sidebar">
<ul>
<li class="list-item">
<a
href="/foo"
class="dynamic-hover-color"
style="color: #{{category.color}};"
>
Category
</a>
</li>
</ul>
</nav>
I'm doing this example using handlebars but the idea is that you take whatever is convenient for your use case to set the inline style (even if it is writing manually the color on hover you want)
You can just use an inline stylesheet statement like this:
<style>#T1:hover{color:red}</style><span id=T1>Your Text Here</span>
You can use the pseudo-class a:hover in external style sheets only. Therefore I recommend using an external style sheet. The code is:
a:hover {color:#FF00FF;} /* Mouse-over link */
You can do id by adding a class, but never inline.
<style>.hover_pointer{cursor:pointer;}</style>
<div class="hover_pointer" style="font:bold 12pt Verdana;">Hello World</div>
It is two lines, but you can reuse the class everywhere.
My problem was that I'm building a website which uses a lot of image-icons that have to be swapped by a different image on hover (e.g. blue-ish images turn red-ish on hover).
I produced the following solution for this:
.container div {
width: 100px;
height: 100px;
background-size: 100px 100px;
}
.container:hover .withoutHover {
display: none;
}
.container .withHover {
display: none;
}
.container:hover .withHover {
display: block;
}
<p>Hover the image to see it switch with the other. Note that I deliberately used inline CSS because I decided it was the easiest and clearest solution for my problem that uses more of these image pairs (with different URL's).
</p>
<div class=container>
<div class=withHover style="background-image: url('https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcQrqRsWFJ3492s0t0NmPEcpTQYTqNnH188R606cLOHm8H2pUGlH')"></div>
<div class=withoutHover style="background-image: url('http://i.telegraph.co.uk/multimedia/archive/03523/Cat-Photo-Bombs-fa_3523609b.jpg')"></div>
</div>
I introduced a container containing the pair of images. The first is visible and the other is hidden (display:none). When hovering the container, the first becomes hidden (display:none) and the second shows up again (display:block).

How can I disable all CSS that can affect my widgets on another website?

I'm building JavaScript widgets that are supposed to be added onto other people's websites.
I style my widgets by dynamically adding a CSS to the pages they're on.
For example,
My CSS code below applies to a DIV inside my widget:
.myWidget { background-color: red; }
But a CSS file outside my own on a remote page might have:
div { border: 5px solid green; }
The CSS above would also apply to my widgets. How can I disable all other CSS outside my own?
Thanks
You could be Using shadow DOM
Shadow DOM MDN Web Docs
An important aspect of web components is encapsulation — being able to keep the markup structure, style, and behavior hidden and separate from other code on the page so that different parts do not clash, and the code can be kept nice and clean. The Shadow DOM API is a key part of this, providing a way to attach a hidden separated DOM to an element.
You can use the all shorthand property and the unset keyword to set each property's value to its initial value.
.myWidget {
all:unset;
background-color: red;
}
div {
background-color:yellow;
}
<div class="myWidget">Hello World!</div>

How to prevent styles from reaching into div

I have an interesting situation I'm trying to find a solution to.
There is a script that needs to be included that builds an HTML element on the page. The issue is that there are global defaults CSS styles that are interacting with this built element and preventing it from functioning.
So our ".core-design form" has a property that is being applied to this built element's form. None of our style needs to be used, as the script is calling in its own stylesheet.
Is there a way to prevent the div containing this element from getting any and all styles from our .core-design?
Edit: To add some clarity as to specifics.
1) The core-design class is attached to every page across many sites.
2) The sub-elements being targeted are the element names, not classes.
3) I am able to add styling to target the div around the generated content, but want to avoid modifying .core-design stylesheet due to its scope.
4) The generated content pulls in its own stylesheet.
5) I have no control over the content being pulled in, and it may change in the future.
6) Codepen of the situation I am currently in
body {
// the .core-design is applied here which contains the form styles.
}
form {
min-height:300px;
min-width:300px;
background-color:black;
}
<body>
<div class="controlled">
<div class="generated">
<form>
<!--
I need to prevent this form/generated div from inheriting any styles. Including any other sub-components inside of it. The only item I 'control' is the wrapping div.
-->
</form>
</div>
</div>
</body>
Yes, there's a way. You can use the all CSS property. More info here https://developer.mozilla.org/en-US/docs/Web/CSS/all.
There's no support for IE :(, but there are polyfills available.
This should reset all styles:
div.className * {
all: initial;
all: unset;
}
Solution 1:
Simple, it is all about CSS selector.
Add a class called ignore-this to the form you want to be ignored.
Then update the global css to have form:not(.ignore-this).
Example below, CSS applied to 1st form but skip the 2nd form.
.core-design form:not(.ignore-this) {
background: red;
}
<div class="core-design">
<form>
form 111111
</form>
<form class="ignore-this">
form 222222
</form>
</div>
Solution 2 (updated)
since you have no control over the core-design css, what you could do is to add a css rule like the following and add the class name to the form you want to reset CSS style:
form.ignore-this{
all: unset;
}
The CSS all shorthand property resets all properties, apart from unicode-bidi and direction, to their initial or inherited value.
REF: https://developer.mozilla.org/en/docs/Web/CSS/all
.core-design form {
background: red;
border: 2px solid green;
}
form.ignore-this{
all: unset;
}
<div class="core-design">
<form>
form 111111
</form>
<form class="ignore-this">
form 222222
</form>
</div>
Not so clear but i think you are having css override issues.
If you know the names of the classes and ids the div has you can change you ids and class names of the core-design so they wouldnt be the same.
Like:
if you have a class named .navi and the div contains .navi css will try to either override that of the div or that of the core depends.
Make sure your cores class and id names are unique from that of the div

Ways to choose color theme of a website

On some websites you can choose a color theme of a website by clicking a button. Seems like nothing sophisticated, however is there any state of the art techniques to do that (maybe toggle between classes throughout a page or call different css files)?
Give your body a color class.
For example <body class="color-green">. You can toggle the class via JS:
document.body.classList.toggle('color-green').
In your CSS you have to create color-aware selectors:
.button {
color: blue;
}
.color-green .button {
color: green;
}
In my opinion that's the way to go.
If you create a lot of color rules in your CSS you should probably seperate them into their own files and include them when the change-color button is clicked.
i find the new css3 solutions very helpfull also the js:
element.classList.add('className');
element.classList.remove('className');
element.classList.toggle('className');
element.classList.contains('className');// check first
and so if you want to change the whole page's style you need to start from the highest element as you can't style parent nodes with css ...
example 1
with more than 2 classes
body.class1{color:blue}
body.class1>div{color:blue}
body.class1>div>a>p>whatever:hover{color:blue}
body.class2{color:green}
body.class2>div{color:green}
/*the div's inside the body with class 'class2' have a green font*/
body.class2>div>a>p>whatever:hover{color:green}
in this case you change the style to the whole page by just calling
body.classList.remove('class1');
body.classList.add('class2');
example 2
with 2 classes (one default and extra)
body{color:blue}
body>div{color:blue}
body>div>a>p>whatever:hover{color:blue}
body.extra{color:green}
body.extra>div{color:green}
body.extra>div>a>p>whatever:hover{color:green}
js:
body.classList.toggle('extra');
you can also change the whole css.. depends on how much your really wanna change.
or create the rules dynamically with javascript
https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet.insertRule
myStyle.insertRule("#blanc { color: white }", 0);
but i think the first one is the simplest to handle...
also if you have a container which will be displayed as grid,rows large icons the simplest solution is just to create a class on the parent container.like in example 1.
tip:another thing i use alot lately is hsla (hue,saturation,lightness,alpha);
i use this if i want to have the background and the font the same color but the font just slightly darker:
background-color:hsla(360,100%,20%,1);// 20% light
color:hsla(360,100%,80%,1);// 80% light

Guidelines for class naming when building a framework/tool

I am developing a small tool with JavaScript that generates a lot of HTML & CSS & I am planning to ship a stylesheet with the JavaScript so it all renders correctly. I am trying to make sure I do not run in obvious stylesheet collisions, so I am looking for guidelines, best practices etc... for the naming of classes that will be used in a framework/tool.
What do you use that works well for naming to avoid collisions?
If you're generating the HTML too why not add a distinctive class or id to the container and then your CSS can simply style up only those elements within your container.
HTML:
<div class="myWierdAndWonderfulGeneratedThing">
<p><label>foo<label><span>bar</span></p>
</div>
CSS:
.myWierdAndWonderfulGeneratedThing label { color: red; }
.myWierdAndWonderfulGeneratedThing span { color: blue; }
You might also use JavaScript to generate unique ids for your wrappers and corresponding style rules.
HTML:
<div id="myWierdAndWonderfulGeneratedThing_0001">
...
</div>
CSS:
#myWierdAndWonderfulGeneratedThing_0001 label { color: green; }

Categories