skip to Main Content

I wanna do a simple trick with only using html and css. I only changed to replace the buttons but only first one worked. And Do I have to use Js İf I want to do that like second one ? or Is there a solution without Js ? and I want to know what cause it. İs it about HTML render ? and Can I implement another way to fix that( buttons are down of container ) with small trick except using Js…

First One (it’s working…)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equi="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    
    body {
      height: 100vh;
    }
    
    .container {
      margin: 50px auto;
      width: 500px;
      height: 500px;
      border: 1px solid black;
    }
    
    .content {
      width: 100px;
      height: 150px;
      background-color: aqua;
      animation: animasyon 1.5s linear alternate infinite;
    }
    
    .start:focus~.container .content {
      animation-play-state: running;
    }
    
    .stop:focus~.container .content {
      animation-play-state: paused;
    }
    
    @keyframes animasyon {
      from {
        width: 100px;
      }
      to {
        width: 500px;
      }
    }
  </style>
</head>

<body>
  <button class="start">Start</button>
  <button class="stop">Stop</button>
  <div class="container">
    <div class="content"></div>
  </div>
</body>

</html>

Second One (it’s not working…)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    
    body {
      height: 100vh;
    }
    
    .container {
      margin: 50px auto;
      width: 500px;
      height: 500px;
      border: 1px solid black;
    }
    
    .content {
      width: 100px;
      height: 150px;
      background-color: aqua;
      animation: animasyon 1.5s linear alternate infinite;
    }
    
    .start:focus~.container .content {
      animation-play-state: running;
    }
    
    .stop:focus~.container .content {
      animation-play-state: paused;
    }
    
    @keyframes animasyon {
      from {
        width: 100px;
      }
      to {
        width: 500px;
      }
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="content"></div>
  </div>
  <button class="start">Start</button>
  <button class="stop">Stop</button>
</body>

</html>

4

Answers


  1. The general sibling selector does not select a sibling that is BEFORE the element, only after. Your buttons are AFTER the sibling in the one that does not work.

    If you want to do with it after, you would need to use a parent and use :has()

    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    
    body {
      height: 100vh;
    }
    
    .container {
      margin: 50px auto;
      width: 500px;
      height: 500px;
      border: 1px solid black;
    }
    
    .content {
      width: 100px;
      height: 150px;
      background-color: aqua;
      animation: animasyon 1.5s linear alternate infinite;
    }
    
    .wrapper:has(.start:focus) > .container .content {
      animation-play-state: running;
    }
    
    .wrapper:has(.stop:focus) > .container .content {
      animation-play-state: paused;
    }
    
    @keyframes animasyon {
      from {
        width: 100px;
      }
      to {
        width: 500px;
      }
    }
    <div class="wrapper">
      <div class="container">
        <div class="content"></div>
      </div>
      <button class="start">Start</button>
      <button class="stop">Stop</button>
    </div>
    Login or Signup to reply.
  2. The sibling selector does not select a sibling that is BEFORE the element, only after. So need to Keep the order in HTML, but can change the order using CSS of flex.

    <!DOCTYPE html>
        <html lang="en">
    
        <head>
          <meta charset="UTF-8">
          <meta http-equi="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
          <style>
            * {
              padding: 0;
              margin: 0;
              box-sizing: border-box;
            }
            
            body {
              height: 100vh;
            }
            
            .container {
              margin: 50px auto;
              width: 500px;
              height: 500px;
              border: 1px solid black;
            }
            
            .content {
              width: 100px;
              height: 150px;
              background-color: aqua;
              animation: animasyon 1.5s linear alternate infinite;
            }
            
            .start:focus~.container-wrapper .content {
              animation-play-state: running;
            }
            
            .stop:focus~.container-wrapper .content {
              animation-play-state: paused;
            }
            
            @keyframes animasyon {
              from {
                width: 100px;
              }
              to {
                width: 500px;
              }
            }
            body {
              display: flex;
              flex-wrap: wrap;
            }
            .container-wrapper {
              width: 100%;
              order: -1;
            }
            .start {
              margin-right: 5px;
            }
          </style>
        </head>
    
        <body>
          <button class="start">Start</button>
          <button class="stop">Stop</button>
          <div class="container-wrapper">
            <div class="container">
              <div class="content"></div>
            </div>
          </div>
        </body>
    
        </html>
    Login or Signup to reply.
  3. As mentionned by everyone, your issue is about the structure.

    You may use labels and hidden radio buttons instead.
    Keep the radios ahead in the flow, and put the link labels anywhere you need within the document, they will trigger the radios.

    read about the for attribute to understand how it works:

    https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/for

    The for attribute is an allowed attribute for <label> and <output>. When used on a <label> element it indicates the form element that this label describes. When used on an <output> element it allows for an explicit relationship between the elements that represent values which are used in the output.

    possible example hit start to run animation and stop for pause.

    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    
    body {
      height: 100vh;
    }
    
    .container {
      margin: 50px auto;
      width: 500px;
      height: 500px;
      border: 1px solid black;
    }
    
    .content {
      width: 100px;
      height: 150px;
      background-color: aqua;
      animation: animasyon 1.5s linear alternate infinite;
    }
    /* hide radios */
    #start,
    #stop {
      position: fixed;
      margin-inline-start: -100vw;
    }
    /* make label look alike button */
    [for="start"],
    [for="stop"] {
      display: inline-block;
      background: silver;
      padding: 0.25em 0.5em 0.1em;
      border-radius: 5px;
      border: outset 1px;
    }
    
    [for="start"]:active,
    [for="stop"]:active {
      border: inset 1px;
    }
    
    #start:checked~.container .content {
      animation-play-state: running;
    }
    
    #stop:checked~.container .content {
      animation-play-state: paused;
    }
    
    @keyframes animasyon {
      from {
        width: 100px;
      }
      to {
        width: 500px;
      }
    }
    <input type="radio" name="anime" id="start"> <input type="radio" name="anime" id="stop">
    <div class="container">
      <div class="content"></div>
    </div>
    <label for="start" class="start">Start</label>
    <label for="stop" class="stop">Stop</label>
    Login or Signup to reply.
  4. Placing the buttons after .container will invalidate the general sibling combinator (~). How about creating an envelope and place the buttons within that? That way the .container will still be a sibling of the buttons.

    Something like (adapted a bit for better display in the snippet run box):

    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    
    body {
      height: 100vh;
      padding: 1rem;
    }
    
    .envelope {
      text-align: center;
      height: 180px;
      width: 300px;
      border: 1px dotted #999;
    }
    
    .envelope button {
      top: 75%;
      position: relative;
    }
    
    .container {
      margin: 20px auto;
      width: 200px;
      height: 80px;
      border: 1px solid black;
    }
    
    .content {
      width: 100px;
      height: 40px;
      animation: animasyon 1.5s linear alternate infinite;
    }
    
    div .stop:hover~.container .content {
      animation-play-state: paused;
    }
    
    @keyframes animasyon {
      from {
        background-color: red;
        width: 0px;
      }
      to {
        width: 200px;
        background-color: green;
      }
    }
    <div class="envelope">
      <button class="stop">Stop</button>
      <div class="container">
        <div class="content"></div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search