Home > other >  I am trying to make background that changes color with a color panel using html and css
I am trying to make background that changes color with a color panel using html and css

Time:11-01

how the website looks like

Hi, I am trying to make a panel that changes the color of my background,when you click on a specific color the background should change accordingly.I managed to code the panel with help of a :target, but i struggle with background change. I tried using :focus, :checked and some more pseudo-classes but i can not make it work. I am not allowed to use JS.

HTML BODY

<div >
        <div id="niketext">NIKE</div>
    </div>
    <div >
        <div id="header">
            <div id="title">Nike Zoom KD 12</div>
            <div >NEW</div>
            <div style="font-size:15px;font-weight:300;">Men's Running Shoes</div>
            <br>
            <div style="font-size:20px;font-weight:500">Product Info</div>
            <div style="font-size:13px;font-weight:300">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nobis distinctio odit praesentium tempora commodi ea iusto veniam fuga minima, tenetur sequi voluptatibus voluptas id! Minima perferendis voluptatibus sint molestias quisquam!</div>
            <br>
            <div style="font-size:20px;font-weight:500">Color</div>
            <div >
                <a href="#red"  id="red"></a>     //I am using :target  for color select effect
                <a href="#green"  id="green"></a>
                <a href="#blue"  id="blue"></a>
                <a href="#orange"  id="orange"></a>
                <a href="#gray"  id="gray"></a>
            </div>
        </div>
    </div>

I've been struggling with CSS, tried something like this:

.colors-selector a#red:focus .shoe-background{
      background: red;
}

.colors-selector a#red:focus ~.shoe-background{
      background: red;
}

.picker ~.shoe-background{
      background: red;
}

#red:target .shoe-background{
    background:red;
}
//and so on...

but I cant make it working, I know it is an issue with a parent-child-sibling specifiers, but I do know what to even search for to have a grasp on the issue. Any help appreciated!

CodePudding user response:

It would be achieveable if you make the "background" to be below the actual selector for picking the color. Below i wrap your color selector and nike, and reverse it on the html structure. After that i re reverse it by using display flex, direction row reverse. After that you could normally use it like below

/*
.colors-selector a#red:focus .shoe-background{
      background: red;
}

.colors-selector a#red:focus ~.shoe-background{
      background: red;
}

.picker ~.shoe-background{
      background: red;
}


#red:target .shoe-background{
    background:red;
}
*/

/* answer */

.colors-selector a#red:focus ~.shoe-background{
      background: red;
}
.textpanel:has([name="color"][value="red"]:checked) ~ .shoe-background{
  background:red
}
.textpanel:has([name="color"][value="green"]:checked) ~ .shoe-background{
  background:green
}
.textpanel:has([name="color"][value="blue"]:checked) ~ .shoe-background{
  background:blue
}
.textpanel:has([name="color"][value="orange"]:checked) ~ .shoe-background{
  background:orange
}
.textpanel:has([name="color"][value="gray"]:checked) ~ .shoe-background{
  background:gray
}
/* Helper */
.card-container{
   display:flex; flex-direction:row-reverse;
}

[value="red"] {
    background: red;
  }
  [value="blue"] {
    background: blue;
  }
  [value="green"] {
    background: green;
  }
  [value="orange"] {
    background: Orange;
  }
  [value="gray"] {
    background: gray;
  }
    input {
    margin: 0 10px;
    appearance: none;
    border: 2px solid;
    border-radius: 50%;
    height: 40px;
    min-height: 40px;
    width: 40px;
    min-width: 40px;
  }

  input:checked {
    border: 6px solid white;
    outline: 1px solid;
  }
<div >
  
  <div >
      <div id="header">
          <div id="title">Nike Zoom KD 12</div>
          <div >NEW</div>
          <div style="font-size:15px;font-weight:300;">Men's Running Shoes</div>
          <br>
          <div style="font-size:20px;font-weight:500">Product Info</div>
          <div style="font-size:13px;font-weight:300">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nobis distinctio odit praesentium tempora commodi ea iusto veniam fuga minima, tenetur sequi voluptatibus voluptas id! Minima perferendis voluptatibus sint molestias quisquam!</div>
          <br>
          <div style="font-size:20px;font-weight:500">Color</div>
          <div >
              <input type="radio" checked value="red" name="color"> red
              <input type="radio" value="green" name="color"> green
              <input type="radio" value="blue" name="color"> blue
              <input type="radio" value="orange" name="color"> orange
              <input type="radio" value="gray" name="color"> gray
          </div>
      </div>
  </div>
  <div >
      <div id="niketext">NIKE</div>
  </div>
</div>

CodePudding user response:

If you change your HTML slightly, to put the color pickers before the NIKE element, then it can be done with CSS.

You need the color pickers to be ahead in the flow so that they can influence the background color of the NIKE element.

This snippet has the pickers as radio buttons all in the same group (defined by their name attribute) so only one can be chosen at once.

I haven't copied all your styling as it wasn't in the question and obviously you'll want to play around with the formatting and the styling of the inputs.

The positioning is done with a grid with 6 columns. The first one is half the width of the container and the following 5 take up the remaining half equally. This is to allow your 5 pickers to each be in a column.

The rest of the text occupies the 5 last columns in the grid and the first row. The pickers occupy the second row second half.

input[type="radio"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  display: inline-block;
  width: 15px;
  height: 15px;
  padding: 3px;
  background-clip: content-box;
  border: 1px solid var(--c);
  background-color: var(--c);
  border-radius: 50%;
}

input[type="radio"]:checked {
  padding: 0;
  width: 20px;
  height: 20px;
}

.shoe-background {
  display: grid;
  grid-template-columns: 5fr repeat(5, 1fr);
  grid-template-rows: 1fr 1fr;
  /* for demo */
  width: 500px;
  height: 500px;
  border: 2px solid black;
}

.picker {
  grid-row: 2;
  width: 25%;
}

#red {
  accent-color: red;
  grid-column: 2;
  --c: red;
}

#green {
  accent-color: green;
  grid-column: 3;
  --c: green;
}

#blue {
  accent-color: blue;
  grid-column: 4;
  --c: blue;
}

#orange {
  accent-color: orange;
  grid-column: 5;
  --c: orange;
}

#gray {
  grid-column: 6;
  --c: gray;
}

#red:checked~#niketext {
  background: red;
}

#green:checked~#niketext {
  background: green;
}

#blue:checked~#niketext {
  background: blue;
}

#yellow:checked~#niketext {
  background: yellow;
}

#gray:checked~#niketext {
  background: gray;
}

#niketext {
  grid-column: 1;
  grid-row: 1 / span 2;
}

.textpanel {
  grid-column: 2 / span 5;
  grid-row: 1;
}

</style><style>input[type="radio"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  display: inline-block;
  width: 15px;
  height: 15px;
  padding: 3px;
  background-clip: content-box;
  border: 1px solid var(--c);
  background-color: var(--c);
  border-radius: 50%;
}

input[type="radio"]:checked {
  padding: 0;
  width: 20px;
  height: 20px;
}

.shoe-background {
  display: grid;
  grid-template-columns: 5fr repeat(5, 1fr);
  grid-template-rows: 1fr 1fr;
  /* for demo */
  width: 500px;
  height: 500px;
  border: 2px solid black;
}

.picker {
  grid-row: 2;
  width: 25%;
}

#red {
  accent-color: red;
  grid-column: 2;
  --c: red;
}

#green {
  accent-color: green;
  grid-column: 3;
  --c: green;
}

#blue {
  accent-color: blue;
  grid-column: 4;
  --c: blue;
}

#orange {
  accent-color: orange;
  grid-column: 5;
  --c: orange;
}

#gray {
  grid-column: 6;
  --c: gray;
}

#red:checked~#niketext {
  background: red;
}

#green:checked~#niketext {
  background: green;
}

#blue:checked~#niketext {
  background: blue;
}

#yellow:checked~#niketext {
  background: yellow;
}

#gray:checked~#niketext {
  background: gray;
}

#niketext {
  grid-column: 1;
  grid-row: 1 / span 2;
}

.textpanel {
  grid-column: 2 / span 5;
  grid-row: 1;
}
<div >

  <input type="radio"  id="red" name="color">
  <input type="radio"  id="green" name="color">
  <input type="radio"  id="blue" name="color">
  <input type="radio"  id="orange" name="color">
  <input type="radio"  id="gray" name="color">

  <div id="niketext">NIKE</div>

  <div >
    <div id="title">Nike Zoom KD 12</div>
    <div >NEW</div>
    <div style="font-size:15px;font-weight:300;">Men's Running Shoes</div>
    <br>
    <div style="font-size:20px;font-weight:500">Product Info</div>
    <div style="font-size:13px;font-weight:300">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nobis distinctio odit praesentium tempora commodi ea iusto veniam fuga minima, tenetur sequi voluptatibus voluptas id! Minima perferendis voluptatibus sint molestias quisquam!</div>
    <div style="font-size:20px;font-weight:500" id="color">Color</div>

  </div>
</div>

CodePudding user response:

1- With your HTML structure, I don't think it's possible with only CSS.

I did a new HTML structure and it only works if the inputs and the background element are in one container. also, the background element should be after the inputs. I couldn't understand why, hopefully, someone expert will help me understand.

2- Doing this with only CSS is easy if you don't consider responsiveness.

but if you want responsive design it's a little difficult and needs a lot of consideration.

I tried to make it kind of responsive here. but it worked only for desktop.

* {
    margin: 0;
    padding: 0;
}

.container {
    display: flex;
    flex-direction: row-reverse;
    height: 80vh;
    width: 80vw;
    padding: 10px 20px;
    margin: auto;
    align-items: center;
    background-color: lightgray;
    position: relative;
}

.text {
    position: absolute;
    top: 5%;
    right: 10%;
}

.text :nth-child(n){
    margin: 10px 0;
}

.bg {
    background-color: gray;
    height: 50%;
    width: 50%;
    max-width: 400px;
    min-width: 300px;
    margin: 20px;
    color: white;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 60px;
    font-family: Arial, Helvetica, sans-serif;
  }

  input {
    margin: 0 10px;
    appearance: none;
    border: 2px solid;
    border-radius: 50%;
    height: 30px;
    min-height: 30px;
    width: 30px;
    min-width: 30px;
  }

  input:checked {
    border: 6px solid white;
    outline: 1px solid;
  }

  .black {
    background: black;
  }
  .blue {
    background: blue;
  }
  .green {
    background: green;
  }
  .orange {
    background: Orange;
  }

  input[value="black"]:checked ~ .bg {
    background-color: black;
  }
  input[value="blue"]:checked ~ .bg {
    background-color: blue;
  }
  input[value="green"]:checked ~ .bg {
    background-color: green;
  }
  input[value="orange"]:checked ~ .bg {
    background-color: orange;
  }
<div >

    <div >
        <h1 >headline</h1>
        <p >details</p>
    </div>
    <input  type="radio" value="black" name="color">
    <input  type="radio" value="blue" name="color">
    <input  type="radio" value="green" name="color">
    <input  type="radio" value="orange" name="color">
    <div >NIKE</div>

</div>

  • Related