Search code examples
cssgrid

The right way to implement pressed button effect in CSS


I am creating piano layout using CSS. I really like this "button-pressed" effect, but it shifts elements around it. How does one avoid it?

<main>
    <div id="o-2" class="octave">
        <button id="C2" class="C key"></button>
        <button id="C2-sharp" class="C-sharp key-black"></button>
        <button id="D2" class="D key"></button>
        <button id="D2-sharp" class="D-sharp key-black"></button>
        <button id="E2" class="E key"></button>
    </div>
</main>
main {
    width: 100%;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

.octave {
    display: grid;
    grid-template-rows: 25% 25% 25% 25%;
    grid-template-columns: repeat(14, auto);
}

button {
    border: 1px solid black;
    margin: 1px;
    box-shadow: 5px 5px 5px black;
    cursor: pointer;
}

button:active {
    margin-left: 4px;
    margin-top: 4px;
    box-shadow: 1px 1px 5px black;
}

Positioning of keys are implemented using grid. Thanks!


Solution

  • You can use the transform property instead of adjusting the margin in the :active pseudo-class. The transform property allows you to scale the button slightly and move it down when it is pressed, without affecting the layout of surrounding elements.

    ...
    button {
      border: 1px solid black;
      margin: 1px;
      box-shadow: 5px 5px 5px black;
      cursor: pointer;
      transition: transform 0.2s ease; /* Add a smooth transition */
    }
    
    button:active {
      transform: scale(0.95) translateY(3px); /* Scale down and move down */
      box-shadow: 1px 1px 5px black;
    }