20 hand-coded CSS social buttons for blogs, SaaS marketing pages, e-commerce product pages, creator bio pages and support widgets. Covers share and follow controls, the Web Share API with a working fallback menu, prefilled intent URLs, live share counts, standalone sign-in button sets, Linktree-style link stacks and direct-message contact cards. Brand marks are inline SVG with no icon font and no external request. Scoped under .soc-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.

14 pure CSS6 light JSPublished

Related34 CSS Floating Buttons25 CSS Footer Designs30 CSS Login Forms20 CSS Copy Buttons

Inline SVG Social Icon Bar No Icon Fonts — preview
01 / 20Pure CSS

Inline SVG Social Icon Bar No Icon Fonts

The reference build the rest of this collection reuses: six hand-drawn inline SVG marks in a horizontal bar, each carrying its own brand colour as a custom property on the anchor so one shared rule styles all six. No icon font, no sprite sheet, no network request — the icons ship inside the markup and inherit colour through currentColor. Hover lifts the mark and tints its surface.

Published

Social Button Hover with Brand Color Fill — preview
02 / 20Pure CSS

Social Button Hover with Brand Color Fill

Brand colour floods each button from the bottom edge on hover, and the label and mark invert to white as the fill passes beneath them. The fill is a transformed pseudo-element — scaleY() on a ::before with transform-origin at the bottom — not a background-position hack and not a width transition, so it stays on the compositor and never triggers layout.

Published

Accessible Circular Social Icon Buttons — preview
03 / 20Pure CSS

Accessible Circular Social Icon Buttons

Icon-only circles done the way an audit wants them: a visually-hidden label utility built on clip-path, an aria-label on every control, a two-pixel focus-visible ring with offset, and a genuine 46px target around a 20px glyph. Focus reveals the hidden label as a caption under the row, so the technique teaches itself while you tab through it.

Published

Social Icon Buttons with CSS Tooltips — preview
04 / 20Pure CSS

Social Icon Buttons with CSS Tooltips

A tooltip that shows the account handle, opens on hover and on keyboard focus, and is genuinely removed from the page at rest rather than sitting invisible on top of your layout. Built with display:none plus transition-behavior: allow-discrete and @starting-style, so it animates in both directions without a line of JavaScript.

Published

Staggered Social Icon Entrance Animation — preview
05 / 20Pure CSS

Staggered Social Icon Entrance Animation

Six marks rise and fade in sequence on load, each one offset by a per-child animation-delay. A checkbox lets you replay the sequence with no JavaScript by swapping to a second identical keyframe set. The reduced-motion block does the thing most builds get wrong: it removes the motion and pins the icons at full opacity instead of leaving them stuck invisible.

Published

Web Share API Button with Fallback Menu — preview
06 / 20Light JS

Web Share API Button with Fallback Menu

One control, two behaviours: on a device that supports the native share sheet it calls navigator.share and hands off to the operating system; everywhere else it opens a styled menu of channel buttons. The feature check runs before the call, the abort path is swallowed silently, and the fallback menu is the shipped baseline rather than an emergency patch.

Published

Social Share Buttons with Intent URLs — preview
07 / 20Pure CSS

Social Share Buttons with Intent URLs

Share links that are just links: each anchor points at a platform intent endpoint with the title and URL already encoded into the query string, so the whole row works with JavaScript switched off. The demo shows which parameter each platform actually reads — they disagree, and sending the wrong one silently drops your copy.

Published

Share Button with Live Count Badge — preview
08 / 20Light JS

Share Button with Live Count Badge

A share control with the running total beside it. The figure uses tabular-nums so digits occupy identical widths and the badge never jitters as the number changes, a short scale pulse marks each increment, and counts above a thousand collapse to 1.2K. State lives in aria-pressed and every change is announced through a polite live region.

Published

Copy Link Button with Copied Feedback — preview
09 / 20Light JS

Copy Link Button with Copied Feedback

A share-this-page control: the URL sits in a monospace field, one button copies it, and the confirmation is driven by the result of the write rather than by optimism. When the clipboard is unavailable — an insecure origin, a locked-down frame — the button says so and pre-selects the text instead of showing a confirmation that never happened.

Published

Article Email and Print Action Bar — preview
10 / 20Light JS

Article Email and Print Action Bar

The quiet pair of controls every long-form page needs: an email link with subject and body already filled in, and a print button that calls window.print(). A small print stylesheet removes the bar itself from the printed page, which is the detail almost every implementation forgets — readers should not get a row of dead buttons on paper.

Published

Sign In with Google Apple GitHub Buttons — preview
11 / 20Pure CSS

Sign In with Google Apple GitHub Buttons

The provider button set on its own — no email field, no divider, no form wrapper. Three full-width blocks with the mark pinned left and the label optically centred, each on the surface its provider expects: a bordered white block, a true black block, and a dark slate block. Sized as real auth targets at 3.25rem with focus rings that survive on every surface.

Published

Follow Button with Following Toggle — preview
12 / 20Light JS

Follow Button with Following Toggle

Follow becomes Following, and hovering Following reveals Unfollow in red — the three-state affordance real products ship. All three labels occupy the same grid cell, so the button never changes width as the state changes. A single data-state attribute drives every visual, and aria-pressed carries the same fact to assistive technology.

Published

Linktree Style Bio Page Link Buttons — preview
13 / 20Pure CSS

Linktree Style Bio Page Link Buttons

A self-hosted link-in-bio stack: monogram avatar and handle at the top, then full-width channel buttons each with a leading mark and a trailing chevron that slides on hover. One column, real anchors, no framework — the version you paste into a personal site instead of renting a hosted page.

Published

Product Share Row with Wishlist Compare — preview
14 / 20Light JS

Product Share Row with Wishlist Compare

The secondary action row that sits under a product title: share, wishlist and compare. The heart fills and throws a small burst when saved, compare flips to a checked state, and both are single aria-pressed toggles rather than class juggling. Enough product chrome to read as a real page, no more.

Published

WhatsApp Telegram Signal Contact Buttons — preview
15 / 20Pure CSS

WhatsApp Telegram Signal Contact Buttons

A static support card of direct-message buttons: WhatsApp, Telegram and Signal, each in its own brand colour with a prefilled deep link. It sits in the page as a contact block — not a corner-pinned floating bubble — so it works inside a help section, a footer column or a product support tab, with a realistic reply-time line above it.

Published

Neumorphic Soft UI Social Buttons — preview
16 / 20Pure CSS

Neumorphic Soft UI Social Buttons

Soft-UI social buttons that actually press: a light shadow at the top-left, a dark one at the bottom-right, and both inverted to inset on :active so the control sinks into the surface. Because low-contrast edges are the known failure of this style, every button also carries a brand-coloured icon and a real focus ring rather than relying on shadow alone.

Published

Glassmorphic Social Buttons over an Image — preview
17 / 20Pure CSS

Glassmorphic Social Buttons over an Image

Frosted social buttons floating over a photograph: backdrop-filter blur with a saturation boost, a hairline inner highlight along the top edge, and a translucent border that reads as glass thickness. A @supports block declares a solid fallback first, so browsers without backdrop-filter get an opaque button instead of an unreadable one.

Published

Ghost Outline Social Buttons Brand Hover — preview
18 / 20Pure CSS

Ghost Outline Social Buttons Brand Hover

Border-only buttons in a neutral resting state that fill with the channel's brand colour on hover and on focus. Border, background and label transition together on one easing so the change reads as a single motion rather than three effects arriving at different times — the restrained option for pages where the social row is not the primary action.

Published

Gradient Social Buttons Animated Border — preview
19 / 20Pure CSS

Gradient Social Buttons Animated Border

A conic gradient rotates around each button's edge while the face stays flat and readable. The rotation works because the angle is a custom property registered with @property — an unregistered property is just a string, cannot be interpolated, and is the single most common reason this effect silently does nothing.

Published

Dark Mode Social Buttons CSS Variables — preview
20 / 20Pure CSS

Dark Mode Social Buttons CSS Variables

A theme-aware social row with a working light and dark switch and no JavaScript at all. A visually-hidden checkbox holds the state and :has() on the demo root rewrites the custom properties, so one :checked flips every colour — including the brand tokens, which are lightened for dark surfaces rather than reused unchanged. Dark is the default; data-theme is the host override.

Published

FAQ

Frequently asked questions

How do I add social media icons without Font Awesome?
Paste the mark straight into your markup as an inline SVG. A social icon is a handful of path data, and inlining it removes an entire font file, a render-blocking stylesheet and a network round trip from your critical path — an icon font that ships hundreds of glyphs to render six is the most common avoidable weight on a marketing page. Give the SVG fill="currentColor" and it inherits whatever colour the link already has, so hover and focus states need no extra rules. One caveat catches people: currentColor only inherits if the path does not hard-code its own fill, and most copied marks do, so strip any fill="#1DA1F2" from the path before wondering why your hover colour does nothing. Set the brand colour once as a custom property on each item — style="--brand:#0a66c2" — and a single shared rule can tint every channel differently. Mark the SVG aria-hidden="true" and put the accessible name on the link, or a screen reader announces nothing at all.
Why are my icon-only social buttons inaccessible?
Because an anchor containing only an SVG has no accessible name. Screen readers announce it as "link" with no indication of where it goes, which makes a row of six identical announcements. Two fixes work: aria-label="Follow us on LinkedIn" on the link, or visually-hidden text inside it. Prefer the hidden text if you also want the label to survive translation tools, which sometimes skip attributes. The visually-hidden utility must use the clip-path pattern rather than display:none or visibility:hidden — both of those remove the element from the accessibility tree entirely, which is the opposite of what you want. The second common failure is size. An icon-only control is frequently drawn at 24px, but WCAG 2.5.8 asks for a 24px minimum and 44px is the practical target on touch; pad the link rather than scaling the glyph so the icon stays crisp while the hit area grows. Finally, never remove the focus ring without replacing it — outline:none on a social row is the single most common keyboard regression in this pattern.
How does the Web Share API work and what is the fallback?
navigator.share({ title, text, url }) opens the operating system's own share sheet, which is why it feels native on mobile and why it can reach apps your page knows nothing about. It returns a promise, so wrap it in try/catch and treat a rejection as ordinary — a user dismissing the sheet rejects with an AbortError, which is not a failure worth reporting. Three constraints decide whether you can call it at all. It requires a secure context, so HTTPS or localhost. It requires a genuine user gesture, so calling it from a timer, on page load, or after an await that breaks the gesture chain will throw. And desktop support is uneven, so a fallback is not optional. Feature-detect with if (navigator.share) and fall back to your own menu of channel links built on intent URLs. Do not detect by user agent; the capability varies by browser and context, not by device class.
What are social share intent URLs and how do I build them?
An intent URL is a plain link that opens a platform's composer with your content prefilled, so sharing needs no SDK, no script tag and no third-party cookie. The shape is a base URL plus query parameters: X reads text and url, LinkedIn reads url, Facebook reads u, and Reddit reads title and url. Every value must be passed through encodeURIComponent separately — encoding the whole query string at once double-encodes the ampersands and the platform silently drops everything after the first parameter, which is the usual reason a share arrives with a title and no link. Two details matter for safety and behaviour. Any link with target="_blank" needs rel="noopener", or the opened page gets a reference to your window through window.opener and can navigate it. And if you open the composer with script instead of a link, pop-up blockers will stop the call unless it happens directly inside a click handler.
How do I stop a share count badge from jittering?
Set font-variant-numeric: tabular-nums on the badge. By default most proportional fonts draw a 1 much narrower than a 0, so a counter ticking from 1,099 to 1,100 visibly reflows and the whole button twitches. Tabular figures give every digit the same advance width, so the number changes without the layout moving. Pair it with font-feature-settings: 'tnum' 1 if you need to cover older rendering paths. Two related traps show up in the same component. If you animate a pulse on increment by removing and re-adding a class in the same frame, the animation will not restart — the browser has not finished a style recalculation, so force a reflow or wait for the next requestAnimationFrame before re-adding. And if the count can grow by an order of magnitude, reserve the width with min-inline-size in ch units rather than letting the badge resize when the first four-digit number arrives.
How do I build a follow button that toggles to Following?
Hold the whole thing in one attribute. A single data-state of idle or following on the button drives every visual difference through attribute selectors, and aria-pressed carries the same state to assistive technology so the change is announced rather than merely seen. The detail that separates a polished build from a janky one is width. Swapping the label with textContent resizes the button and shoves whatever sits next to it, so stack both labels in a single grid cell — grid-area: 1 / 1 on each — and crossfade opacity between them. The button then keeps one width for every state. Real products also show a destructive affordance: hovering Following reveals Unfollow in red. Declare that on :focus-visible as well as :hover, or the option simply does not exist for keyboard users. Keep the revert honest — if the network call fails, put the state back rather than leaving an optimistic Following that lies about what the server knows.
Why does my glassmorphic or gradient-border social button render wrong?
Two separate causes, both silent. For frosted glass, backdrop-filter stops working when an ancestor combines overflow: hidden with a transform, because that ancestor creates a containing block the filter cannot sample through. Nothing errors; the blur just vanishes. Always declare a solid background first and add the glass behind @supports (backdrop-filter: blur(1px)), or unsupported browsers render near-invisible buttons over a photo. For an animated gradient border, the usual failure is that the rotation does nothing at all: a bare custom property is just a string to the browser, so it cannot be interpolated. Register it first with @property --angle declaring syntax: '<angle>', an initial value and inherits: false, and the same keyframes suddenly animate. The registration must sit at the top level of the stylesheet, not nested inside a selector block.
How do these port to React, Vue, Svelte and Tailwind?
The CSS ports unchanged — every .soc-NN selector and custom property is framework-agnostic, and the fourteen pure-CSS demos need no JavaScript in any framework. Where behaviour exists, the shape is the same everywhere: one piece of state plus a small handler. In React a follow toggle is const [following, setFollowing] = useState(false) driving a data-state attribute, and any success-window timer must be cleared in the effect cleanup or a rapid re-click leaves a stale timeout that resets the label early. Vue uses a ref with onBeforeUnmount; Svelte a plain let and the cleanup returned from onMount. One trap is specific to server-rendered frameworks like Next and Nuxt: navigator.share and navigator.clipboard do not exist during the server pass, so feature-detect inside an effect or an event handler rather than in the component body, which would otherwise throw a reference error at build time. For Tailwind, the brand colour custom property survives as an arbitrary value and the states map to data-[state=following]: variants.

Related collections

30 CSS Badges preview

30 CSS Badges

30 hand-coded CSS badges for status indicators, notifications, membership tiers, live-data displays, and SEO / DevOps / financial dashboards — upload progress, typing indicator, transit line status, Core Web Vitals, ECG heartbeat, CI/CD build pipeline, countdown ring, live price ticker, keycap shortcut, wax seal, conference lanyard, and holographic collectibles. Copy-paste HTML and CSS, WCAG 2.2 accessible, MIT licensed.

20 CSS Banners & Alerts preview

20 CSS Banners & Alerts

20 hand-coded CSS banner and alert bars for e-commerce storefronts, SaaS dashboards, marketing sites, and compliance-bound products. Covers GDPR cookie consent with a real preferences panel, promo bars with countdown timers, free-shipping threshold progress, app-install smart banners, maintenance and incident status bars, newsletter signup bars, age verification gates, limited-stock urgency banners, live event announcements, browser upgrade notices, geo and currency switchers, sticky top announcement bars, bottom cookie bars, inline form validation alerts, icon-aligned alert banners, left-border accent alerts, diagonal stripe promos, full-width hero banners, animated gradient border alerts, and a text-wrapping laboratory that shows five strategies for the unbreakable string that breaks more banners than anything else. Every bar is scoped under a .ba-NN prefix for no-collision pasting, guards prefers-reduced-motion, carries the correct aria-live and role semantics, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.

25 CSS Blockquotes preview

25 CSS Blockquotes

25 hand-coded CSS blockquote designs for SaaS testimonials, editorial pull quotes, documentation callouts, and developer engineering blogs: large decorative quotation marks with ::before / ::after glyphs, Tailwind CSS blockquote component, pure CSS callout / admonition boxes for Docusaurus / Mintlify / Nextra documentation, responsive center-aligned quote banners, modern minimalist left-border editorial style, animated CSS gradient border, classic left border, brutalist high-contrast, glassmorphism frosted card, glowing neon border, article pull quote with text-wrap, speech bubble chat-style, thick vertical accent rail, customer testimonial cards with avatar and star rating, inline highlighted text, marker highlight underline, floating drop-shadow, aurora gradient background, Twitter / X card style, multi-column newspaper editorial, IDE code-comment style, Markdown-compatible defaults, JavaScript testimonial quote slider, expandable read-more, and one-click copy button. 22 Pure CSS + 3 Light JS (slider, expand, copy). Every design scoped under .bq-NN prefix for no-collision pasting, prefers-reduced-motion guarded per WCAG 2.3.3, WCAG 2.2 AA accessible, framework-agnostic (React, Vue, Svelte, Astro, Next.js, Nuxt, Remix, SvelteKit).

Search CodeFronts

Loading…