Iza Adamska
Iza Adamska

Reputation: 39

Change background based on different hovered element

When hovering on each circle at the corner, background color in the main area should be changed so matches the color of the circle, and there is an adequate paragraph showing at the same time.

I have tried transition, opacity... but couldn't get it work.

Note, HTML has to be untouched.

* {
  margin: 0;
  padding: 0;
}

body {
  position: relative;
  height: 100vh;
  text-align: center;
}

p {
  font-family: Arial, Helvetica, sans-serif;
  color: white;
}

.bg {
  position: relative;
  height: 100vh;
  background-color: #333;
}

.circle {
  height: 10px;
  width: 10px;
  border-radius: 50%;
  border: white solid 2px;
  z-index: 1;
}

.red.circle {
  position: absolute;
  top: 10%;
  left: 10%;
  background-color: red;
}

.green.circle {
  position: absolute;
  top: 10%;
  right: 10%;
  background-color: green;
}

.blue.circle {
  position: absolute;
  bottom: 10%;
  left: 10%;
  background-color: blue;
}

.orange.circle {
  position: absolute;
  bottom: 10%;
  right: 10%;
  background-color: orange;
}

p.red {
  display: none;
  background-color: red;
  line-height: 100vh;
}

p.green {
  display: none;
  background-color: green;
  line-height: 100vh;
}

p.blue {
  display: none;
  background-color: blue;
  line-height: 100vh;
}

p.orange {
  display: none;
  background-color: orange;
  line-height: 100vh;
}
<div class="red circle"></div>
<div class="green circle"></div>
<div class="blue circle"></div>
<div class="orange circle"></div>
<div class="bg">
  <p class="red">Czerwony</p>
  <p class="green">Zielony</p>
  <p class="blue">Niebieski</p>
  <p class="orange">Pomarańczowy</p>
</div>

Upvotes: 2

Views: 59

Answers (3)

soulshined
soulshined

Reputation: 10602

Since they are somewhat in the same hierarchy, you can take advantage of the ~ general sibling selector which matches the second element only if it follows the first element (though not necessarily immediately):

/* added */

.red.circle:hover ~ .bg  {
  background-color: red;
}
.green.circle:hover ~ .bg {
  background-color: green;
}
.blue.circle:hover ~ .bg {
  background-color: blue;
}
.orange.circle:hover ~ .bg {
  background-color: orange;
}
.red.circle:hover ~ .bg p.red { display: block; }
.green.circle:hover ~ .bg p.green { display: block; }
.blue.circle:hover ~ .bg p.blue { display: block; }
.orange.circle:hover ~ .bg p.orange { display: block; }
/* end of edit */

* {
  margin: 0;
  padding: 0;
}

body {
  position: relative;
  height: 100vh;
  text-align: center;
}

p {
  font-family: Arial, Helvetica, sans-serif;
  color: white;
}

.bg {
  position: relative;
  height: 100vh;
  background-color: #333;
  transition: background-color 0.5s ease-in;
}

.circle {
  height: 10px;
  width: 10px;
  border-radius: 50%;
  border: white solid 2px;
  z-index: 1;
}

.red.circle {
  position: absolute;
  top: 10%;
  left: 10%;
  background-color: red;
}

.green.circle {
  position: absolute;
  top: 10%;
  right: 10%;
  background-color: green;
}

.blue.circle {
  position: absolute;
  bottom: 10%;
  left: 10%;
  background-color: blue;
}

.orange.circle {
  position: absolute;
  bottom: 10%;
  right: 10%;
  background-color: orange;
}
p {
  transition: background-color 1s ease-in;
}
p.red {
  display: none;
  background-color: red;
  line-height: 100vh;
}

p.green {
  display: none;
  background-color: green;
  line-height: 100vh;
}

p.blue {
  display: none;
  background-color: blue;
  line-height: 100vh;
}

p.orange {
  display: none;
  background-color: orange;
  line-height: 100vh;
}
<div class="red circle"></div>
<div class="green circle"></div>
<div class="blue circle"></div>
<div class="orange circle"></div>
<div class="bg">
  <p class="red">Czerwony</p>
  <p class="green">Zielony</p>
  <p class="blue">Niebieski</p>
  <p class="orange">Pomarańczowy</p>
</div>

You can add transition on the .bg class for the desired effect.

Upvotes: 3

Temani Afif
Temani Afif

Reputation: 272937

I would simplify your code to rely on pseudo element and data-attribute for background and content. It will be then easier to control as you don't need any complex selector:

body {
  margin: 0;
  background: #333;
  min-height: 100vh;
}

.circle {
  position: absolute;
  height: 10px;
  width: 10px;
  border-radius: 50%;
  border: white solid 2px;
}

.circle::before {
  content: attr(data-text);
  font-family: Arial, Helvetica, sans-serif;
  text-align: center;
  color: white;
  line-height: 100vh;
  font-size: 80px;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: -2;
  background: inherit;
  opacity: 0;
  transition: 1s;
}

.circle:hover::before {
  opacity: 1;
}

.circle.red {
  top: 10%;
  left: 10%;
  background: red;
}

.circle.green {
  top: 10%;
  right: 10%;
  background: green;
}

.circle.blue {
  bottom: 10%;
  left: 10%;
  background: blue;
}

.circle.orange {
  bottom: 10%;
  right: 10%;
  background: orange;
}
<div class="circle red" data-text="Czerwony"></div>
<div class="circle green" data-text="Zielony"></div>
<div class="circle blue" data-text="Niebieski"></div>
<div class="circle orange" data-text="Pomarańczowy"></div>

Upvotes: 2

davbuc
davbuc

Reputation: 537

The css only solution of @soulshined is great, but just in case anyone wants to use javascript - here's a hint:

const bg = document.querySelector(".bg");
const circles = document.querySelectorAll(".circle");

circles.forEach(circle => circle.addEventListener("mouseenter", (e) => {
  const style = getComputedStyle(e.target);
  const backgroundColor = style.backgroundColor;

  bg.style.backgroundColor = backgroundColor;
}))

Upvotes: 1

Related Questions