Alex Stiles
Alex Stiles

Reputation: 161

Why is there a random space when you click on this button?

I have been trying to replicate some material design buttons but have run into an issue with the div that is generated to create the "ripple" effect. If you go to my codepen at https://codepen.io/AlexStiles/pen/oPomzX you will see the issue.

This is caused by the div (I tried deleting it and it fixed the problem). I have tried adding a variety of properties such as font-size and line-height to no avail. Interestingly, depending on your browser the issue seems to have a different effect. On safari the width increases hugely then it decreases to the chrome width.

"use strict";

const buttons = document.getElementsByTagName("button");
const overlay = document.getElementsByClassName("overlay");
const animationTime = 600;

for (let i = 0; i < buttons.length; i++) {
    buttons[i].addEventListener("click", createRipple);
};

let circle = document.createElement("div");

function createRipple(e) {

    this.appendChild(circle);

    var d = Math.max(this.scrollWidth, this.scrollHeight);

    circle.style.width = circle.style.height = d + "px";

    circle.style.left = e.clientX - this.offsetLeft - d / 2 + "px";
    circle.style.top = e.clientY - this.offsetTop -  d / 2 + "px";

    circle.classList.add("ripple");
    // setTimeout(function(){
    //     for (let i = 0; i < circle.length; i++)
    //     document.getElementsByClassName("ripple")[i].remove();
    // }, animationTime);
}
button {
    background-color: #4888f1;
    border-radius: 24px;
    display: flex;
    align-items: center;
    outline: 0;
    border: 0;
    padding: 10px 22px;
    cursor: pointer;
    overflow: hidden;
    position: relative;
}

button .ripple {
    position: absolute;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.5);
    transform: scale(0);
    animation: ripple 0.5s linear;
    font-size: 0;
    line-height: 0;
}

@keyframes ripple {
    to {
        transform: scale(2.5);
        opacity: 0;
    }
}

button img {
    width: 20px;
    height: 20px;
}

button *:not(:last-child) {
    margin: 0 8px 0 0;
}

button span {
    color: #fff;
    font-family: Futura;
}

@media screen and (min-width: 1280px) {
    button {
        padding: 0.8vw 1.75vw;
        border-radius: 1.9vw;
    } button img {
        width: 1.55vw;
        height: auto;
    } button span {
        font-size: 0.8vw;
    }
}
<html>
    <head>
        <title>Material Design Components</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <button>
        <span>Add to Cart</span>
    </button>
    <script src="js.js"></script>
</html>

Upvotes: 3

Views: 165

Answers (2)

Temani Afif
Temani Afif

Reputation: 273530

When you add the ripple element you make it the last-child thus the rule of margin button *:not(:last-child) will apply to span since this one is no more the last child.

To fix this remove margin from the span:

"use strict";

const buttons = document.getElementsByTagName("button");
const overlay = document.getElementsByClassName("overlay");
const animationTime = 600;

for (let i = 0; i < buttons.length; i++) {
    buttons[i].addEventListener("click", createRipple);
};

let circle = document.createElement("div");

function createRipple(e) {

    this.appendChild(circle);

    var d = Math.max(this.scrollWidth, this.scrollHeight);

    circle.style.width = circle.style.height = d + "px";

    circle.style.left = e.clientX - this.offsetLeft - d / 2 + "px";
    circle.style.top = e.clientY - this.offsetTop -  d / 2 + "px";

    circle.classList.add("ripple");
    // setTimeout(function(){
    //     for (let i = 0; i < circle.length; i++)
    //     document.getElementsByClassName("ripple")[i].remove();
    // }, animationTime);
}
button {
    background-color: #4888f1;
    border-radius: 24px;
    display: flex;
    align-items: center;
    outline: 0;
    border: 0;
    padding: 10px 22px;
    cursor: pointer;
    overflow: hidden;
    position: relative;
}

button .ripple {
    position: absolute;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.5);
    transform: scale(0);
    animation: ripple 0.5s linear;
    font-size: 0;
    line-height: 0;
}

@keyframes ripple {
    to {
        transform: scale(2.5);
        opacity: 0;
    }
}

button img {
    width: 20px;
    height: 20px;
}

button *:not(:last-child) {
    margin: 0 8px 0 0;
}

button span:first-child {
    color: #fff;
    font-family: Futura;
    margin:0;
}

@media screen and (min-width: 1280px) {
    button {
        padding: 0.8vw 1.75vw;
        border-radius: 1.9vw;
    } button img {
        width: 1.55vw;
        height: auto;
    } button span {
        font-size: 0.8vw;
    }
}
<html>
    <head>
        <title>Material Design Components</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <button>
        <span>Add to Cart</span>
    </button>
    <script src="js.js"></script>
</html>

Upvotes: 1

benjamin c
benjamin c

Reputation: 2338

Change

button *:not(:last-child) {
    margin: 0 8px 0 0;
}

To,

button *:not(:last-child) {
    margin: 0 0 0 0;
}

Checked in firefox.

Upvotes: 4

Related Questions