Using CSS to target a style other than itself - javascript

It might only be possible with JavaScript, but I was wondering if it was possible to link one style to another with events like :focus or :hover in CSS alone.
For example, could the class "hitArea" change the "changeArea" background attribute when in focus?
.changeArea { background: yellow; }
.hitArea div:focus { changeArea:changeBG; }
.changeArea changeBG { background: blue; }
I know there is communication between styles when doing CSS animations, like in this working example:
.reveal {
position:absolute;
top:190px;
left:0px;
margin-left:0px;
-webkit-animation-name:reveal;
-webkit-animation-duration:0.1s;
-webkit-animation-fill-mode:backwards;
-webkit-animation-delay:0.2s;
animation-name:reveal;
animation-duration:0.1s;
animation-fill-mode:backwards;
animation-delay:0.2s;
}
#-webkit-keyframes reveal {
0% { left:-900px; -webkit-animation-timing-function:linear; }
99% { left:-900px; -webkit-animation-timing-function:linear; }
100% { left:0px; }
}
So what is the syntax, or is it even possible, for me to communicate between other styles?

If your HTML looks like this:
<div class="hitarea">
<div class="changeArea"></div>
</div>
Then you can target changeArea when hitArea is focused like this:
.hitarea:focus .changeArea {
background-color: red;
}
This will only work when "changeArea" is some child of hitarea.
Read more on CSS Selectors and what you can do with them here: https://developer.mozilla.org/en-US/docs/CSS/Getting_Started/Selectors

I don't believe it is possible. You can take a look at http://sass-lang.com/ which allows you to do things like that.

If .changeArea is a child of .hitArea, yes!
.hitArea:focus .changeArea{ /* Styles to apply when .hitarea is hovered */ }
If that's not what you want, I recommend setting it up so that when .hitArea is focused, javascript applies a class to .changeArea that has the style you want to apply.

Related

JavaScript media query vs CSS media query

I've noticed that the JavaScript media query seems to take effect after the CSS equivalent ones.
I've created two examples demonstrating what I'm talking about:
First example
HTML:
<div class="foo">
bar
</div>
CSS:
.foo {
background-color: orange;
}
#media(max-width: 300px) {
.foo {
background-color: blue;
transform: translateY(100px);
transition: all 300ms ease-out;
}
}
jsbin link is: here
Here transition happens, when screen width becomes 300px or less from something bigger.
But when creating responsive design such transition can be annoying. I'm trying to get rid of them. The following Javascript and CSS solves the problem, but I'm not sure that is it reliable or not.
2nd example
HTML
<div class="foo">
bar
</div>
<button>toggle translateY to 200px</button>
CSS
.transition {
transition: all 300ms ease-out;
}
.foo {
background-color: orange;
}
#media(max-width: 300px) {
.foo {
background-color: blue;
transform: translateY(100px);
}
}
.translateY {
transform: translateY(200px);
}
JavaScript:
const w = window.matchMedia("(max-width: 300px)");
const div = document.querySelector(".foo");
const button = document.querySelector('button');
function fun(e) {
if (e.matches) {
div.classList.add('transition');
} else {
div.classList.remove('transition');
}
}
// for initial screen width change detection
fun(w);
w.addEventListener('change', fun);
button.onclick = function() {
div.classList.toggle('translateY');
}
jsbin link is here
Here it seems the following thing happens in order when screen width becomes 300px or less from something bigger:
CSS transform: translateY(100px) is rendered in a flash.
transition class is added to div by JavaScript.
By clicking the button, it makes sure that the transition class is working.
This example doesn't cause any unwanted transition as screen size becomes 300px or less from something bigger.
So it seems that any CSS media query is rendered before JavaScript equivalent media queries. I think it's a good thing. But I'm not sure, is it the standard well supported behavior? Is it safe to build logic based on this behavior?
This is part of the CSS specificity
Inline styles added to an element (e.g., style="font-weight: bold;") always overwrite any styles in external stylesheets, and thus can be thought of as having the highest specificity.
The javascript code you posted will add inline styles (through the style property of the element) and thus has the highest specificity. (it has nothing to do with the js media query, it just has to do with how you apply the style in the JS to the element)
Update after the comments/update in question
Again it depends on when you load the CSS and the JS. If you first include the CSS file, since it is a render blocking resource, it will be applied first.
I am not sure though, why don't you apply all the rules through CSS media queries ?
const div = document.querySelector(".foo");
const button = document.querySelector('button');
button.onclick = function() {
div.classList.toggle('translateY');
}
.foo {
background-color: orange;
}
#media(max-width: 300px) {
.foo {
background-color: blue;
transform: translateY(100px);
transition: all 300ms ease-out;
}
}
.translateY {
transform: translateY(200px);
}
<div class="foo">
bar
</div>
<button>toggle translateY to 200px</button>

Is it possible to assign a class to :root?

As I am thinking about solutions to another problem of mine, I am trying to understand to which extend CSS elements can inherit from other elements. Specifically, having the following definition
.dark {
background-color: black;
}
.light {
background-color: white
}
is it possible to programmatically assign (with JS, probably) one of these classes to the :root element?
It can be done easily with JS.
Select the element:
const root = document.querySelector(':root')
Assign the class to it:
root.classList.add('light')
All together:
const root = document.querySelector(':root')
root.classList.add('light')
Or, instead of having two classes, it might be better to have a :not() selector:
:root:not(.dark){
background-color: white;
}
:root.dark{
background-color: black;
}
I would use (and have used) CSS variables for this.
:root {
--background-color: black;
}
.background {
background-color: var(--background-color);
}
Then change the CSS variable with javascript.
In HTML, :root is equivalent to <html> (doc):
In HTML, :root represents the element and is identical to the
selector html, except that its specificity is higher.
A possible solution would be to apply the class to <html>:
document.getElementsByTagName("html")[0].classList.add('dark')
.dark {
background-color: red;
}
<html>
hello
</html>

Changing the background color and the main content background in wordpress

I've been searching on this topic for almost 1 hour and I couldn't find an answer, as you know most youtube videos out there are completely useless. My website is on WordPress and I would like to change the background color, and the main content in specific pages
Here's the code that I tried to add to the Custom CSS box
.page-id-2
{
background: #FFFFFF
}
.page-id-2 .content {
background: #FFFFFF
}
It didn't do anything
Here my website: www.graspdating.com
Try this. The selector you want is an ID (#) not a Class (.)
EDIT
.page-id-2 #content,
.page-id-2 #content article,
.page-id-2 #content #search-2,
.page-id-2 #content .enl-widget-title,
.page-id-2 #content #secondary,
.page-id-2 #content .arc-entry-meta { background-color: #FFFFFF }
This should completely "white-out" the background of the content area. If there are certain elements you want to have a different color, you can remove accordingly.
You will need to override the current class properties using another class properties. There are different ways in which properties can be overridden. Assuming you have the following for your .site-content:
.blog .site-content { background: #eeeeee;}
e.g. any of the following would override it:
.blog .site-content { background: red !important;}
body .blog .site-content { background: red;}
.page-id-2 .blog .site-content { background: red;}
body.page-id-2 .blog .site-content { background: red;}
the first one "wins" by !important, a blunt instrument... The rest “win” by selector specificity;
By saying that, you can override properties by the selector specificity (https://www.w3schools.com/css/css_specificity.asp) and/or using the !important (https://css-tricks.com/when-using-important-is-the-right-choice/)
You can easily do it using dependency like
body .page-id-2 { background: #FFFFFF; }
similarly you can also use
body.page-id-63 #content { background: #FFFFFF; }

Change Background when part of it is hovered

i am totally new in web design, and i am right now struggling with creating part of my website, i need to somehow make this happen:
When PART of the BODY BACKGROUND is HOVERED, make the background change to "B", and when the mouse is not over that part, I need it to change back to background "A".
I have seen some examples here but as i am a beginner, i have no idea how to use javascript, if you could please give me some light here, either on pure CSS or on how to apply javascript.
This is accomplished very easily using a third party javascript library called JQuery http://jquery.com, you can see a working example here: http://jsfiddle.net/bbp8G/
$(document).ready(function(){
$("#hover").mouseenter(function(){
$(this).css("background","#009900");
}).mouseleave(function(){
$(this).css("background","#ffffff");
});
});
Here's the easiest way I know how to do what you've described...
<!-- POSITION THIS DIV WHEREVER YOU WANT THE
USER TO HOVER SO THAT THE BACKGROUND WILL CHANGE -->
<div id="hover">
</div>
<!-- PUT THIS CODE IN YOUR <HEAD> -->
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js" />
<style>
#hover { width: 200px; height: 200px; position: relative; top: 200px; background: green; }
.myNewBackround { background-color: red; }
</style>
<script>
$(document).ready(function() {
// when the #hover DIV is hovered, change the background of the body
$('#hover').hover(function() {
$('body').addClass('myNewBackground');
});
});
</script>
Here's a JS FIDDLE:
http://jsfiddle.net/ZKaJn/
Or you can do it with pure CSS
<div id="left"> </div>
<div id="right"> </div>
And the CSS part:
#left
{
background-color:#000;
float:left;
width:50%;
height:200px;
}
#right
{
background-color:#FF0;
float:right;
width:50%;
height:200px;
}
#right:hover
{
background-color:#00F;
}
#left:hover
{
background-color:#F00;
}
You can replace the div's and values with whatever you like, the main part is the #right:hover and #left:hover
Actually with just css it is not possible to change the background of the body when hovering a DOM element. This is because CSS does not allow you (yet) to travel up the DOM tree (select a parent), only down (select a child).
That being said, it is however possible to mimic the effect, and it is even quiet easy if it is the body background you want to change. You can lay a pseudo element with a background on top of your body background, and underneath the actual content. This way it looks as if the body background has changed.
The css to achieve this would look something like this:
.hover-me:hover:after {
content: '';
top: 0;
left: 0;
right: 0;
bottom: 0;
position: fixed;
background: url(http://placekitten.com/600/300) center center;
background-size: cover;
z-index: -1;
}
And a small fiddle to demonstrate: http://jsfiddle.net/3dwzt/
Should be compatible with IE8 and up

removeAttr / addClass issue on IE6

This question was asked here but the issue wasn't resolved.
Please see this jsfiddle on IE6 : http://jsfiddle.net/RnsxM/2/
Basically a sprite image (not png fixed) won't update correctly in IE6. The class seems to be applied (and works without javascript) but the combinaison removeAttr + addClass seems broken.
I tried :
!important css statement
use of background-position-x or background-position-y
Does someone know a workaround ?
Not to do with scripting, this is a simple CSS brokenness. Something in IE6's selector engine can't cope with the idea of there being two #id.class rules with the same #id on a single stylesheet. This shorter example demonstrates:
<style type="text/css">
#sprite.pos1 { background: red; }
#sprite.pos2 { background: yellow; }
</style>
<div id="sprite" class="pos2">Hello</div> <!-- White in IE6! -->
You can avoid it by putting the IDs and classes on different elements, or just breaking the stylesheet up into two:
<style type="text/css">
#sprite.pos1 { background: red; }
</style>
<style type="text/css">
#sprite.pos2 { background: yellow; }
</style>
<div id="sprite" class="pos2">Hello</div>
#bobince is right. I'm make a jsfiddle and run it in IEtester and I see that IE6 does not accept the selector:
#sprite.pos1
but accepts:
.pos1
I think basically is that and I recommend you that make an alternative selector for IE6, something like this:
#sprite.pos1 { background-position: -120px 0; }
.pos1 { _background-position: -120px 0; }
#sprite.pos2 { background-position: -240px 0; }
.pos2 { _background-position: -240px 0; }

Categories