Service rows that turn black on hover with a dot sliding in before the title, dotted tags and a description. React and Tailwind CSS.
InvertingServiceRows.tsx
// Service rows that turn black on hover, with a dot sliding in before the
// title, dotted tags and a short description.
// Pure Tailwind, no dependencies. Works with Tailwind v3 and v4.
type Service = { title: string; tags: string[]; description: string };
type Props = {
heading?: string;
services?: Service[];
};
const DEFAULT_SERVICES: Service[] = [
{ title: "Brand identity", tags: ["Strategy", "Logo", "Guidelines"], description: "Identities that work from favicon to billboard." },
{ title: "Web design", tags: ["UX", "UI", "Prototyping"], description: "Clear, fast websites people enjoy using." },
{ title: "Development", tags: ["Next.js", "CMS", "Performance"], description: "Built properly, easy for your team to edit." },
{ title: "Art direction", tags: ["Photography", "Campaigns"], description: "A consistent look across everything you ship." },
];
const Dot = ({ className = "h-[5px] w-[5px]" }: { className?: string }) => <span aria-hidden className={`inline-block shrink-0 rounded-full bg-current ${className}`} />;
export default function ServiceRowsInvert({ heading = "Services", services = DEFAULT_SERVICES }: Props) {
return (
<section className="bg-white px-4 py-20 font-['Inter',ui-sans-serif,system-ui,sans-serif] text-black antialiased md:px-8 md:py-28">
<div className="mx-auto max-w-7xl">
<h2 className="mb-16 text-[clamp(2.5rem,6vw,5rem)] font-semibold leading-none tracking-[-0.04em] md:mb-24">{heading}</h2>
<ul className="flex flex-col gap-2.5">
{services.map((s) => (
<li key={s.title} className="group grid grid-cols-1 gap-4 bg-[#F9F9F9] px-5 py-6 transition-colors duration-300 hover:bg-black hover:text-white md:px-7 lg:min-h-28 lg:grid-cols-12 lg:items-center lg:gap-6 lg:py-0">
<h3 className="flex items-center text-2xl font-medium lg:col-span-5">
<span aria-hidden className="w-0 overflow-hidden transition-all duration-300 group-hover:w-[18px]">
<Dot className="h-2 w-2" />
</span>
{s.title}
</h3>
<ul className="flex flex-wrap gap-2.5 lg:col-span-4">
{s.tags.map((tag) => (
<li key={tag} className="flex items-center gap-2.5 text-sm font-medium">
<Dot />
{tag}
</li>
))}
</ul>
<p className="max-w-[12rem] text-sm font-medium lg:col-span-3 lg:justify-self-end">{s.description}</p>
</li>
))}
</ul>
</div>
</section>
);
}
How to use it
- Make sure your Next.js or React project has Tailwind CSS set up (v3 or v4 both work).
- Create
components/InvertingServiceRows.tsxand paste the code. - Import it into a page and replace the sample text and images with your own.
