Headers
Bubble button with following arrow
31 Oct 2023
HTML
SCSS
PostCSS
JS
<a
href="#"
class="bubble-btn"
>
<span class="bubble-btn__text">
More about us
</span>
<span class="bubble-btn__arrow-wrap">
<div class="bubble-btn__arrow">
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 448 512">
<path d="M438.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.8 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l306.7 0L233.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160z"/></svg>
</div>
</span>
</a>
:root{
--primary-cl: tomato;
--secondary-cl: blueviolet;
--white: white;
}
.bubble-btn {
box-sizing: border-box;
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
padding: 48px 39px;
border-radius: 999px;
background: var(--primary-cl);
color: var(--white);
font-family: sans-serif;
font-weight: 700;
text-decoration: none;
&:hover {
.bubble-btn__arrow {
opacity: 0.5;
transform: scale(1.4);
}
.bubble-btn__arrow.rotate-90 {
transform: scale(1.4) rotate(90deg);
}
}
}
.bubble-btn__text {
position: relative;
z-index: 1;
bottom: 12px;
font-size: 30px;
font-weight: 500;
text-align: center;
pointer-events: none;
}
.bubble-btn__arrow-wrap {
position: absolute;
left: 50%;
top: calc(100% - 44px);
transform: translateX(-50%);
pointer-events: none;
}
.bubble-btn__arrow {
display: flex;
justify-content: center;
align-items: center;
width: 58px;
height: 58px;
border-radius: 999px;
background: var(--secondary-cl);
font-size: 17px;
transition: all ease 250ms;
svg {
fill: var(--white);
}
}
:root{
--primary-cl: tomato;
--secondary-cl: blueviolet;
--white: white;
}
.bubble-btn {
box-sizing: border-box;
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
padding: 48px 39px;
border-radius: 999px;
background: var(--primary-cl);
color: var(--white);
font-family: sans-serif;
font-weight: 700;
text-decoration: none;
&:hover {
.bubble-btn__arrow {
opacity: 0.5;
transform: scale(1.4);
}
.bubble-btn__arrow.rotate-90 {
transform: scale(1.4) rotate(90deg);
}
}
}
.bubble-btn__text {
position: relative;
z-index: 1;
bottom: 12px;
font-size: 30px;
font-weight: 500;
text-align: center;
pointer-events: none;
}
.bubble-btn__arrow-wrap {
position: absolute;
left: 50%;
top: calc(100% - 44px);
transform: translateX(-50%);
pointer-events: none;
}
.bubble-btn__arrow {
display: flex;
justify-content: center;
align-items: center;
width: 58px;
height: 58px;
border-radius: 999px;
background: var(--secondary-cl);
font-size: 17px;
transition: all ease 250ms;
svg {
fill: var(--white);
}
}
const bubbleBtnList = document.querySelectorAll(".bubble-btn");
if (bubbleBtnList.length) {
bubbleBtnList.forEach((btn) => {
const arrowBubble = btn.querySelector(".bubble-btn__arrow-wrap");
btn.addEventListener(
"mousemove",
({ offsetX, offsetY, target: { offsetWidth, offsetHeight } }) => {
arrowBubble.style.left = `${offsetX}px`;
arrowBubble.style.top = `${offsetY}px`;
arrowBubble.style.transform = `translate(-50%, -50%)`;
}
);
btn.addEventListener("mouseenter", () => {
arrowBubble.style.transition =
"width 0.3s ease, top 0.3s ease, left 0.3s ease";
setTimeout(() => {
arrowBubble.style.transition = null;
}, 300);
});
btn.addEventListener("mouseleave", () => {
arrowBubble.style.transition =
"width 0.3s ease, top 0.3s ease, left 0.3s ease";
setTimeout(() => {
arrowBubble.style.left = null;
arrowBubble.style.transform = null;
if (!btn.classList.contains("job-card")) {
arrowBubble.style.top = null;
} else {
arrowBubble.style.top = topPos;
}
setTimeout(() => {
arrowBubble.style.transition = null;
}, 300);
}, 200);
});
});
}