Social Post Card — Free HTML CSS JS Snippet

Social Post Card · Cards · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

toggleLike() flips liked boolean with +1/-1 optimistic count update
.like-btn.active fills the heart icon red via CSS fill/stroke
Follow button toggles .following state: Fill button becomes outline
Hashtag and mention spans with coloured CSS styling
Avatar gradient circle with initials — same pattern as Profile Card
Action row: Like, Repost, Share, Bookmark with icon buttons
Relative timestamp display in post meta row
Export as HTML file, React JSX, or React + Tailwind CSS
Mobile (375px), Tablet (768px), Desktop device preview buttons
Live split-pane editor — preview updates as you type

About this UI Snippet

Social Post Card — Like Toggle, Optimistic Count Update & Follow State

Screenshot of the Social Post Card snippet rendered live

A social post card is the core unit of any social feed — Twitter, LinkedIn, and every social platform uses this pattern. This snippet implements the full card with avatar, name, handle, post content, and an interactive action row (the replies below it use the comment thread pattern).

Optimistic like toggle

toggleLike() flips a liked boolean and toggles .active on the heart button — the same interaction as the standalone favorite button. The count shows 284 or 285 immediately — before any API call. This optimistic UI update is standard practice for responsiveness.

Follow state

The Follow button toggles between "Follow" and "Following" with different visual states via .following class — the same toggle as the profile card and user stats card.

Content styling

Hashtags and mentions use inline <span class="tag"> and <span class="mention"> elements with CSS colour and hover underline — standard social post rendering.

The optimistic like counter

Clicking the like button immediately increments the displayed count without waiting for an API response — this is the optimistic update pattern used by every major social platform. The .liked class toggles to fill the heart icon. If the API call fails in a real implementation, decrement the count and show an error toast notification (see the Toast Notification snippet in this library).

Hashtag and mention styling

Post text containing hashtags and mentions uses distinct colours — blue for mentions, indigo for hashtags — making them visually scannable in a dense feed. In a real feed, these render as anchor links pointing to the hashtag search results page or the mentioned user profile page.

The card action row

Three action buttons (like, comment, share) follow the standard social platform layout. Add a bookmark as a fourth action using the same toggle pattern. All states manage identically: a class toggle on the button icon and a counter update on click. Keep actions icon-only or icon+count depending on the card width and density requirements.

Building a full feed from multiple cards

Render multiple social post cards in a flex-direction: column container with gap: 12px for a feed. Add infinite scroll by observing the last card with IntersectionObserver and fetching the next page when it enters the viewport: const obs = new IntersectionObserver(([e]) => { if(e.isIntersecting) fetchNextPage(); }); obs.observe(lastCard).

The optimistic like counter

Clicking the like button immediately increments the displayed count without waiting for an API response — this is the optimistic update pattern used by every major social platform. The .liked class toggles to fill the heart icon. If the API call fails in a real implementation, decrement the count and show an error toast notification (see the Toast Notification snippet in this library).

Hashtag and mention styling

Post text containing hashtags and mentions uses distinct colours — blue for mentions, indigo for hashtags — making them visually scannable in a dense feed. In a real feed, these render as anchor links pointing to the hashtag search results page or the mentioned user profile page.

The card action row

Three action buttons (like, comment, share) follow the standard social platform layout. Add a bookmark as a fourth action using the same toggle pattern. All states manage identically: a class toggle on the button icon and a counter update on click. Keep actions icon-only or icon+count depending on the card width and density requirements.

Building a full feed from multiple cards

Render multiple social post cards in a flex-direction: column container with gap: 12px for a feed. Add infinite scroll by observing the last card with IntersectionObserver and fetching the next page when it enters the viewport: const obs = new IntersectionObserver(([e]) => { if(e.isIntersecting) fetchNextPage(); }); obs.observe(lastCard).

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't have to trace the optimistic-update logic by hand. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why toggleLike hardcodes the count as 284 versus 285 instead of incrementing or decrementing a variable, and what real-world bug that hardcoded approach would cause if the initial like count varied per post. The same assistant can help optimize it, for instance checking whether the follow button's toggle logic, which mutates textContent directly through an inline onclick, would scale to a feed of fifty post cards without becoming hard to maintain. It is just as useful for extending the card: ask it to add proper rollback-on-failure logic that reverts the like state if a real API call fails, wire up an IntersectionObserver for infinite-scroll loading of more posts, or add a quote-repost flow that opens a composer pre-filled with this post's text. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a Twitter/X-style "social post card" in plain HTML, CSS, and JavaScript — no framework, no libraries.

Requirements:
- A card with a header row containing an avatar (initials on a gradient background), display name, handle, relative timestamp, and a Follow button on the opposite side.
- The Follow button must toggle between two distinct states on click: an outlined "Follow" state and a filled "Following" state, changing both its text content and its background/border styling via a single toggled CSS class.
- Post body text containing inline hashtag spans, styled in a distinct color from the body text and underlined on hover.
- An action row with like, comment (reply), repost, and share buttons, each rendered as an icon plus a count, laid out with equal flexible widths so they distribute evenly regardless of button count.
- Clicking the like button must toggle a liked boolean state, fill the heart icon with a color, and update the displayed count using an actual increment/decrement calculation based on the previous count value (not two hardcoded numbers) — the count must correctly handle being clicked in rapid succession (like, unlike, like again) without drifting from the true value.
- Clicking the repost button must independently toggle its own active visual state (a different accent color from the like button) without affecting the like state.
- Explain in a comment why this immediate, before-the-network-response update is called an "optimistic" UI update, and what should happen to the like state and count if a real API call behind it were to fail.

Step by step

How to Use

  1. 1
    Click the Like buttonClick the heart icon to toggle the like state — the heart fills red and the count updates between 284 and 285.
  2. 2
    Click FollowClick the Follow button to toggle between Follow and Following states.
  3. 3
    Update post contentIn the HTML panel, change the post text, hashtags, mentions, avatar initials, username, and handle.
  4. 4
    Update the action countsChange the Repost and Share count numbers in the HTML panel.
  5. 5
    Add a media attachmentAdd an <img> or video element inside .post-body to show a media attachment below the text.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component, or "Tailwind" for a React + Tailwind version.

Real-world uses

Common Use Cases

Social media feed components
Use as the feed unit in a social platform. The like, repost, and share actions are standard social interactions. Wire each action to API calls and handle the response to persist engagement state across sessions and devices.
Community platform and forum posts
Display user posts in developer communities, forums, and Q&A platforms. The like count, author info, and hashtag styling match user expectations from platforms like Dev.to, GitHub Discussions, and Stack Overflow.
Learn optimistic UI update patterns
toggleLike() updates the count immediately before any API call — this is optimistic UI. The state update feels instant. Add error handling that reverts the optimistic state if the API call fails. This pattern prevents perceived lag in high-latency networks.
Social proof embeds on landing pages
Showcase real social posts about your product on a landing page. Static cards with high like counts and positive mentions from recognisable accounts build credibility without requiring dynamic data fetching.
Content creator analytics previews
Display content creator profile cards with their best-performing post, engagement metrics, and follower count. Used on influencer marketplace platforms where brands browse creator stats.
Wire to a social API with real-time updates
Connect to a WebSocket for real-time like count updates: ws.onmessage = e => { const { postId, likes } = JSON.parse(e.data); if(postId === currentPostId) document.getElementById("like-count").textContent = likes; }. Combine with the optimistic update for immediate local feedback.

Got questions?

Frequently Asked Questions

An optimistic update applies the state change in the UI immediately — before the API call confirms success. The like count changes from 284 to 285 the instant the user clicks, without waiting for a server round-trip. If the API fails, the state reverts. This makes social interactions feel instant even on slow connections.

The Follow button has a clicked handler that toggles .following class on the button element. CSS .follow-btn.following changes background from filled accent to transparent with an accent border, and the text changes from "Follow" to "Following". Clicking again removes .following and resets.

Wrap hashtag text in <span class="tag">#hashtag</span> and mentions in <span class="mention">@handle</span> in the HTML. CSS .tag { color: #6366f1; } and .mention { color: #6366f1; text-decoration: underline; } apply the social platform styling convention.

Add below .post-text: <div class="post-media"><img src="url" alt="Post image" class="post-img"></div>. CSS .post-img { width: 100%; border-radius: 12px; margin-top: 10px; display: block; max-height: 280px; object-fit: cover; } The image clips to the border-radius without overflow.

Calculate the difference from now: const diff = Date.now() - postTimestamp; const mins = Math.floor(diff/60000); const label = mins < 60 ? mins + "m ago" : Math.floor(mins/60) + "h ago". Update the timestamp span on mount and every 60 seconds. For production, use a library like dayjs for edge cases.

Yes. Manage liked and following in useState. Pass post data (author, content, timestamp, initialLikes) as props. Wire API calls inside the handlers: const handleLike = async () => { setLiked(!liked); setCount(c => liked ? c-1 : c+1); try { await api.toggleLike(postId); } catch { setLiked(liked); setCount(c => liked ? c+1 : c-1); } }