htmlcsscss-animationscss-transitionsparent-child

Define both element dimensions based on one parent dimension


:root {
    --success: #0c0;
}

button {
    border: 2px solid;
    border-radius: 10px;
    cursor: pointer;
    margin: 1em 0.5em;
    padding: 10px 15px;
    transition: transform 1s;
}

button:active {
    transform: scale(90%);
}

button.animated {
    background-color: transparent;
    overflow: hidden;
    position: relative;
    transition: color 1s, border-color 1s, transform 0.2s;
    z-index: 1;
}

button.animated:hover {
    border-color: transparent;
}

button.animated::after {
    border: 0;
    border-radius: 50%;
    content: "";
    height: 150%;
    left: -25%;
    opacity: 0;
    position: absolute;
    top: -25%;
    transform: scale(0.1);
    transform-origin: center;
    transition: all 1s;
    width: 150%;
    z-index: -1;
}

button.animated:hover::after {
    opacity: 1;
    transform: scale(1);
}

.text,
button.animated.background::after {
    background-color: white;
}

.background,
button.animated.text:hover{
    color: white;
}

button.animated.text {
    border-color: var(--muted);
}

.success.text,
button.animated.success.background:hover {
    color: var(--success);
}

.success.background,
button.animated.success.text::after {
    background-color: var(--success);
}

button.animated.success.text:hover,
button.animated.success.background {
    border-color: var(--success);
}
<button class="animated success background">Button</button>
<button class="animated success background">Longer button</button>

The button in the snippet above has a background effect in the shape of an ellipse that appears when you hover over it. Currently, the dimensions of the ellipse are proportional to the dimensions of the button. I would like the ellipse to be circular, with its width 141.4% times the longer dimension of the button, or, if not possible, the width of the button. How can I achieve this?


Solution

  • :root {
        --success: #0c0;
    }
    
    button {
        border: 2px solid;
        border-radius: 10px;
        cursor: pointer;
        margin: 1em 0.5em;
        padding: 10px 15px;
        transition: transform 1s;
    }
    
    button:active {
        transform: scale(90%);
    }
    
    button.animated {
        background-color: transparent;
        overflow: hidden;
        position: relative;
        transition: color 1s, border-color 1s, transform 0.2s;
        z-index: 1;
    }
    
    button.animated:hover {
        border-color: transparent;
    }
    
    button.animated::after {
        aspect-ratio: 1 / 1;
        border: 0;
        border-radius: 50%;
        content: "";
        left: 50%;
        opacity: 0;
        position: absolute;
        top: 50%;
        transform: translate(-50%, -50%) scale(0.1);
        transform-origin: center;
        transition: all 1s;
        width: 142%;
        z-index: -1;
    }
    
    button.animated:hover::after {
        opacity: 1;
        transform: translate(-50%, -50%) scale(1);
    }
    
    .text,
    button.animated.background::after {
        background-color: white;
    }
    
    .background,
    button.animated.text:hover{
        color: white;
    }
    
    button.animated.text {
        border-color: var(--muted);
    }
    
    .success.text,
    button.animated.success.background:hover {
        color: var(--success);
    }
    
    .success.background,
    button.animated.success.text::after {
        background-color: var(--success);
    }
    
    button.animated.success.text:hover,
    button.animated.success.background {
        border-color: var(--success);
    }
    <button class="animated success background">Button</button>
    <button class="animated success background">Longer button</button>

    Solved it! I added aspect-ratio: 1 / 1;, set only the width to 142%, and simply used left: 50%;, top: 50%;, and transform: translate(-50%, -50%) to translate the background onto the center of the button. Added transform: translate(-50%, -50%) to :hover::after too, so the circle stays centered when the button is hovered over.