Porting vanilla CSS bubble to Tailwind
I started exploring Tailwind CSS and decided to port one of my favorite CSS codepen in it. I wanted to see what the learning curve looks like and how tailwind actually helps in code management and future maintenance.
The Code repo and stackblitz links:
- https://github.com/ranuzz/tailwind-css-bubble-port
- https://stackblitz.com/github/ranuzz/tailwind-css-bubble-port
The component I picked is an animated CSS sphere that looks like a bubble. The whole process with progression is explained in this post https://cssanimation.rocks/spheres/
The codepen for the version that I’m panning to port.
https://codepen.io/donovanh/pen/nRgZjd
{{< renderhtml `
See the Pen Spheres tutorial: 6 Bubble (animated) by Donovan Hutchinson (@donovanh) on CodePen.
`>}}The CSS in this codepen is pretty clean and but the individual attributes of the component definition are not sharable. Like background color gradients, transforms etc. Tailwind being a utility library makes this process seamless. I was able to replicate most of it using base utility classes and the rest I extended using external plugins and custom components. The final CSS file looks pretty clean and uses building block utility classes to achieve the final result.
.stage {
@apply m-auto w-[200px] h-[200px]
}
.ball {
@apply block relative rounded-full w-full
h-full bg-radial-circle-b-blue-shades-with-stops
before:content-[''] before:absolute before:w-[90%]
before:h-[90%] before:rounded-full
before:top-1 before:left-2
before:bg-radial-circle-none-custom-one-white-with-stops
before:z-10 before:blur-md
after:content-[''] after:absolute after:hidden
after:top-2 after:left-5
after:w-[80%] after:h-[80%] after:rounded-full
after:z-10 after:blur-sm after:rotate-45
}
.bubble {
@apply animate-bubble-anim
bg-radial-circle-none-custom-two-bubble-with-stops
before:blur-xl before:h-[80%] before:w-[40%]
before:translate-x-[131%]
before:translate-y-[58%]
before:rotate-12
before:bg-radial-circle-none-bubble-before-with-stops
after:block after:bg-radial-circle-none-custom-three-bubble-after-with-stops
}
Behind the scene I’m using https://github.com/benface/tailwindcss-gradients
for radial gradient and the extended tailwind looks like this.
module.exports = {
content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
theme: {
radialGradientShapes: {
// defaults to this value
default: "ellipse",
circle: "circle",
},
radialGradientSizes: {
// defaults to this value
default: "closest-side",
none: "",
},
radialGradientPositions: {
// defaults to these values
default: "center",
t: "top",
tr: "top right",
r: "right",
br: "bottom right",
b: "bottom",
bl: "bottom left",
l: "left",
tl: "top left",
"custom-one": "50% 0px",
"custom-two": "50% 55%",
"custom-three": "50% 80%",
"custom-four": "130% 130%",
},
radialGradientColors: {
// defaults to {}
red: "#f00",
"black-white-with-stops": ["#000", "#000 45%", "#fff 55%", "#fff"],
"blue-shades-with-stops": [
"#81e8f6",
"#76deef 10%",
"#055194 80%",
"#062745 100%",
],
"white-with-stops": ["#ffffff", "rgba(255, 255, 255, 0) 58%"],
"bubble-with-stops": [
"rgba(240, 245, 255, 0.9)",
"rgba(240, 245, 255, 0.9) 40%",
"rgba(225, 238, 255, 0.8) 60%",
"rgba(43, 130, 255, 0.4)",
],
"bubble-after-with-stops": [
"rgba(255, 255, 255, 0)",
"rgba(255, 255, 255, 0) 74%",
"white 80%, white 84%",
"rgba(255, 255, 255, 0) 100%",
],
"bubble-before-with-stops": [
"rgba(255, 255, 255, 0) 0",
"rgba(255, 255, 255, 0) 46%",
"rgba(255, 255, 255, 0.8) 50%",
"rgba(255, 255, 255, 0.8) 58%",
"rgba(255, 255, 255, 0) 60%",
"rgba(255, 255, 255, 0) 100%",
],
},
extend: {
animation: {
"bubble-anim": "bubble-keyframes 2s ease-out infinite",
},
keyframes: {
"bubble-keyframes": {
"0%": { transform: "scale(1)" },
"20%": { transform: "scaleY(0.95) scaleX(1.05)" },
"48%": { transform: "scaleY(1.1) scaleX(0.9)" },
"68%": { transform: "scaleY(0.98) scaleX(1.02)" },
"80%": { transform: "scaleY(1.02) scaleX(0.98)" },
"97%, 100%": { transform: "scale(1)" },
},
},
},
},
plugins: [require("tailwindcss-gradients")],
};
The complexity is hidden in the tailwind config file but, IMO, it is much more manageable than vanilla CSS. Tailwind documentation and plugin ecosystem was a huge help in this port.