Changing an unrelated div on hover [duplicate] - css

This question already has answers here:
Is there a CSS parent selector?
(33 answers)
Is there a "previous sibling" selector?
(30 answers)
Closed 1 year ago.
Is there a purely (S)CSS solution to change an unrelated (i.e. not a sibling or a child) div on hover, as I am trying to do in the code below?
.blue,.green {
width: 5rem;
height: 3rem;
margin: 1rem;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
&:hover {
background-color: lightgreen;
}
&:hover .blue {
background-color: lightblue; // trying to effect this change
}
}
<div>
<div class="blue" />
</div>
<div>
<div class="green" />
</div>
Here is the CodePen.
Update: the reply by #alekskorovin is outstanding and deserves many upvotes!

In CSS there are possibilities to use the same parent and common classes and :not selector together with CSS variables. As far as I could understand the thing is to set some common properties when you hover on some of the items. If it's possible to have a common parent element you could consider that example (https://codepen.io/alekskorovin/pen/bGobvzG):
:root {
--bg: rgba(255, 255, 255, 0.3);
}
.one {
background: blue;
}
.two {
background: green;
}
.common {
margin: 1rem;
border: solid 0.1rem grey;
position: relative;
}
.common:before {
content: '';
position: absolute;
width: 100%;
height: 100%;
background: var(--bg);
}
.parent:not(div:hover) {
--bg: rgba(255, 255, 255, 0);
}
<div class="parent">
<article><div class="one common">One</div></article>
<article><div class="two common">Two</div></article>
</div>

Related

How do you style first date and last date of a range p-calendar?

Is there a property to style the first date and last date of a p-calendar from PrimeNG. When styling the p-highlight it changes all elements in the range to the style. Is there a way to specify the first element and last element styles in css to create a range selection like the following:
Are there any other ways to do this other than through css?
html:
<div class="field col-12 md:col-4">
<p-calendar selectionMode="range"></p-calendar>
</div>
Style sheet:
.p-datepicker {
background: whitesmoke;
color: gray;
table {
font-size: 12px;
color:#f4f4f4;
td {
padding: .5rem;
color: black;
&.p-datepicker-other-month{
color: transparent;
}
> span {
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
border: 1px solid transparent;
&.p-highlight {
// Active circle
color: #f4f4f4;
background: orange;
&.p-disabled{
background: transparent;
}
}
}
}
}
}
Didn't found a way to do it by css and I am not sure it could be achieved.
But javascript/typescript should do the job:
.html:
<div class="field col-12 md:col-4">
<p-calendar (onSelect)="onDateSelected($event)" selectionMode="range">
</p-calendar>
</div>
.ts:
onDateSelected(event: any) : void {
const rangeLength = document.getElementsByClassName('p-highlight').length;
document.getElementsByClassName('p-highlight')[0].style.background = 'blue';
if(rangeLength>0)
document.getElementsByClassName('p-highlight')[rangeLength-1].style.background = 'blue';
}

how to select root class variable into another class in css

<style>
:root product6 {
--width:435px;
}
:root .size1 {
--scale: 0.8;
}
:root .size2 {
--scale: 0.7;
}
.productDiv {transform:scale(--scale);}
</style>
<div class="product6 size1"></div>
This is working well if I give classes inside div class attr...showing my div scaled 0.8 and width 435px
But how can I select size1 class inside css syntax under stylesheet
.productDivResponsive {width:435px;transform:scale(???)}
Thanks.
Define your variables in root element (:root), so that they are available everywhere. Then define classes and ids, that use those variables in any way you see fit.
(If you want a narrower scope, you can also define your vars for another element. You do not necessarily have to use :root. Have a look at the special section in my example.)
/* define vars for everywhere, as everything inherits from root */
:root {
--width: 100px;
--height: 100px;
--scale-1: 0.8;
--scale-2: 0.6;
--scale-3: 0.4;
--c-green: #3d9970;
--c-red: #ff4136;
--c-blue: #0074d9;
}
/* define vars for a specific part of your page, overriding root in this example */
#special {
--c-green: #01FF70;
--c-red: #f012be;
--c-blue: #7fdbff;
border: 1px solid #ccc;
}
section {
margin: 10px;
}
main {
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: center;
}
.product {
width: var(--width);
height: var(--height);
box-shadow: inset 0 0 1em rgba(0, 0, 0, 0.4);
color: rgba(60, 60, 60, 0.7);
font-family: sans-serif;
display: flex;
flex-flow: column nowrap;
align-items: center;
justify-content: center;
font-size: 24px;
font-weight: 700;
text-align: center;
background-image: linear-gradient(rgba(255, 255, 255, 0.4), rgba(0, 0, 0, 0.3))
}
.scale-1 {
transform: scale(var(--scale-1));
}
.scale-2 {
transform: scale(var(--scale-2));
}
.scale-3 {
transform: scale(var(--scale-3));
}
#product-2 {
background-color: var(--c-green);
}
#product-3 {
background-color: var(--c-red);
}
#product-4 {
background-color: var(--c-blue);
}
#product-5 {
background-color: var(--c-green);
}
#product-6 {
background-color: var(--c-red);
}
#product-7 {
background-color: var(--c-blue);
}
/* within scope of #special, colors are different: */
#product-10 {
background-color: var(--c-blue);
}
#product-11 {
background-color: var(--c-red);
}
#product-12 {
background-color: var(--c-green);
}
<main>
<section>
<div id="product-1" class="product">1</div>
<div id="product-2" class="product scale-1">2</div>
<div id="product-3" class="product scale-2">3</div>
<div id="product-4" class="product scale-3">4</div>
</section>
<section>
<div id="product-5" class="product scale-3">5</div>
<div id="product-6" class="product scale-2">6</div>
<div id="product-7" class="product scale-1">7</div>
<div id="product-8" class="product">8</div>
</section>
<section id="special">
<div id="product-9" class="product scale-2">9</div>
<div id="product-10" class="product scale-2">10</div>
<div id="product-11" class="product scale-2">11</div>
<div id="product-12" class="product scale-2">12</div>
</section>
</main>
This is working well if I give classes inside div class attr...showing my div scaled 0.8 and width 435px
The code provided cannot possibly work, it's syntactically erroneous.
But how can I select size1 class inside css syntax under stylesheet?
Addition of question mark was my edit.
CSS is static, hard coded, so just write it in just as you have with the rest of your CSS. I hope you are not asking how to dynamically manipulate CSS on the stylesheet because you need to grasp the advanced concepts dealing with CSS and working knowledge of JavaScript.
Demo
Note: Details are commented in demo
/*
Declare CSS variables
:root is the best selector to use because all descendants
will have access to them.
--=These are VALUES ONLY=--
They cannot be assigned to a selector directly
They can only be assigned to a property
propert: value is assigned to a selector
*/
:root {
--w435: 435px;
--scX070: 0.7;
--scX120: 1.2;
}
.box {
background: gold;
color: blue;
outline: 3px solid blue;
margin: 20px auto;
min-height: 30px;
/*
This is the proper syntax when assigning the value of a
CSS variable to a property
${selector} {${property}: var(--${CSSVar});}
.box { width: var(--w435); }
*/
width: var(--w435);
}
.size1 {
transform: scaleX(var(--scX070));
}
.size2 {
transform: scaleX(var(--scX120));
}
<div class='box'></div>
<div class="box size1"></div>
<div class="box size2"></div>
If I use this code I can make that I need...but I don't want to write classes twice...Problem is I want to use divs somewhere static somewhere responsive...
<style>
:root .product6 {
--width:435px;
}
:root .size1 {
--scale: 0.8;
}
:root .size2 {
--scale: 0.7;
}
.productDiv {transform:scale(--scale);}
#media (min-width: 1600px) {
:root {
--scale:0.8;
}
.productDivResponsive {transform:scale(var(--scale));}
}
#media (max-width: 1600px) and (min-width: 1360px) {
:root {
--scale:0.7;
}
.productDivResponsive {transform:scale(var(--scale));}
}
</style>
<div class="product6 productDiv"></div> <!-- This one static and scaling my div 0.8 -->
and want to make it responsive somewhere in my page with writing code something like that;
<div class="productDivResponsive"></div>
my productDivResponsive div must be scaled according to my media queries...
how can I remove repeating root class variables?
I hope I can explain what I need...Possible??

css variables - declare variable if not already defined

I have a project which is split up into the parent app, and several reusable child components in separate repositories. I'd like to define default CSS variables in these child components, which can be overridden by the parent app, however I can't find the right syntax for this. Here's what I've tried:
/* parent */
:root {
--color: blue;
}
/* child */
:root {
--color: var(--color, green);
}
.test {
width: 200px;
height: 200px;
background: var(--color, red);
}
https://codepen.io/daviestar/pen/brModx
The color should be blue, but when the child :root is defined, the color is actually red, at least in Chrome.
Is there a correct approach for this? In SASS you can add a !default flag to your child variables which basically means 'declare if it's not already declared'.
CSS stands for cascading style sheets,
so you cannot override anything by a parent...
The only way is to create a stronger rule.
look at .c1 and .p1
.parent {
--background: red;
}
.child {
--size: 30px;
--background: green; /* this wins */
background-color: var(--background);
width: var(--size);
height: var(--size);
}
.p1 .c1 {
--background: red; /* this wins */
}
.c1 {
--size: 30px;
--background: green;
background-color: var(--background);
width: var(--size);
height: var(--size);
}
<div class="parent">
<div class="child"></div>
</div>
<hr />
<div class="p1">
<div class="c1"></div>
</div>
Thanks to #Hitmands hint I have a neat solution:
/* parent */
html:root { /* <--- be more specific than :root in your parent app */
--color: blue;
}
/* child */
:root {
--color: green;
}
.test {
width: 200px;
height: 200px;
background: var(--color);
}
I would suggest an approach by aliasing the variables in the component and using "parent" or root variables as main value while local value is by !default.
.parent {
--background: red;
}
.child {
--child_size: var(--size, 30px); /* !default with alias */
--child_background: var(--background, green); /* !default with alias */
background-color: var(--child_background);
width: var(--child_size);
height: var(--child_size);
}
<div class="parent">
<div class="child"></div>
</div>
<hr>
<div class="child"></div>

Is there a way to reproduce currentColor with var(--current-color)?

I don't use currentColor very often but when I do, it's extremely useful.
So I've been a little excited about the arrival of CSS Variables.
Let's take a traffic light.
N.B. Please take it on trust from me that Japanese traffic lights go red to amber to blue. I know it's hard to believe. I know the blue light looks sort-of green. But it isn't, it's blue.
div {
float: left;
width: 200px;
}
div div {
float: none;
}
.top {
color: rgb(255,0,0);
}
.middle {
color: rgb(255,227,0);
}
.bottom {
color: rgb(63,255,63);
}
.jp .bottom {
color: rgb(0,255,191);
}
.light {
text-align: center;
}
.light::before {
content: '';
display: block;
margin: 6px auto 0;
width: 25px;
height: 25px;
border-radius: 15px;
background-color: currentColor;
}
<div class="uk">
<h2>UK Traffic Lights</h2>
<div class="top light">Red</div>
<div class="middle light">Amber</div>
<div class="bottom light">Green</div>
</div>
<div class="jp">
<h2>JP Traffic Lights</h2>
<div class="top light">Red</div>
<div class="middle light">Amber</div>
<div class="bottom light">Blue</div>
</div>
Now, the clever thing about
background-color: currentColor;
is that it just reads whatever the current value for color is and uses that.
By contrast...
background-color: var(--current-color);
That can't reference the current value of another style declaration, can it?
So, you'd need to set up 4 variables (just like you need to declare color: 4 times in the styles above):
.top {
--color-top: rgb(255,0,0);
}
.middle {
--color-middle: rgb(255,227,0);
}
.bottom {
--color-bottom: rgb(63,255,63);
}
.jp .bottom {
--color-bottom-jp: rgb(0,255,191);
}
And then... you need to reference each of those different variables later on. Which means a different background-color declaration for each variable:
.top::before {
color: var(--color-top);
background-color: var(--color-top);
}
.middle::before {
color: var(--color-middle);
background-color: var(--color-middle);
}
.bottom::before {
color: var(--color-bottom);
background-color: var(--color-bottom);
}
.jp .bottom::before {
color: var(--color-bottom-jp);
background-color: var(--color-bottom-jp);
}
Really?!
That can't be right. Have I missed something?
Is there no way to reproduce currentColor with var(--current-color) ?
Is there no way for CSS variables to represent the current value of another style declaration?
Actually, you can set a CSS custom property instead of setting directly the color property, and use it for color and background-color.
/* Set global variable inside the :root scop */
:root {
--color-top: rgb(255,0,0);
}
div {
float: left;
width: 200px;
}
div div {
float: none;
}
/* Set the local --color variable, according to your need */
.top {
--color: var(--color-top);
}
.middle {
--color: rgb(255,227,0);
}
.bottom {
--color: rgb(63,255,63);
}
.jp .bottom {
--color: rgb(0,255,191);
}
.light {
color: var(--color);
text-align: center;
}
.light::before {
content: '';
display: block;
margin: 6px auto 0;
width: 45px;
height: 45px;
border-radius: 15px;
background-color: var(--color);
}
<div class="uk">
<h2>UK Traffic Lights</h2>
<div class="top light">Red</div>
<div class="middle light">Amber</div>
<div class="bottom light">Green</div>
</div>
<div class="jp">
<h2>JP Traffic Lights</h2>
<div class="top light">Red</div>
<div class="middle light">Amber</div>
<div class="bottom light">Blue</div>
</div>
I do not really understand why you are not using background-color: currentColor, because it works well in your own example.
If you are using SASS (which is compiled into css), then you can use SASS variables. The code will look like :
$font-stack: Helvetica;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
more informations on the SASS official website

Rating system using CSS (hover from left to right)

Is there a simple way to reverse the colour order when hovering?
Using this trick here I have the order right > left:
&:hover,
&:hover ~ button {
color: red
}
The fiddle with the right > left: https://jsfiddle.net/celio/Lowc1ruh/
Example with the left > right: https://css-tricks.com/examples/StarRating/
It is impossible for me to use float, position: absolute; and anything that changes the right order of my current html.
Plain CSS example:
button {
margin: 0;
padding: 5px;
border: none;
background: transparent;
display: inline-block;
}
button:before {
content: "⋆";
font-size: 5rem;
line-height: 1;
}
button:hover,
button:hover ~ button {
color: red;
}
<div class="wrapper">
<button></button>
<button id="2"></button>
<button></button>
<button></button>
<button></button>
</div>
One way would be to make all the child button elements color: red; when hovering over .wrapper. Then use the sibling selector (~) to change any elements after the currently hovered element to color: black;.
You should remove any whitespace between the elements (in this case I put them into one line in the HTML) to ensure that the cursor is always hovering over a star.
Example with plain CSS:
.wrapper button {
margin: 0;
padding: 5px;
border: none;
background: transparent;
display: inline-block;
}
.wrapper button:before {
content: "⋆";
font-size: 5rem;
line-height: 1;
}
.wrapper button:hover ~ button {
color: black;
}
.wrapper:hover button {
color: red;
}
<div class="wrapper">
<button></button><button id="2"></button><button></button><button></button><button></button>
</div>
JS Fiddle using SASS

Resources