Styling Guide
Styling Guide
The React and Vue components ship unstyled: there is no bundled CSS. You bring your own styles. This keeps the SDK tiny and lets the blog match your site exactly.
You have three levels of control:
data-rankhikerattribute selectors on the default markup.- Class props (
className/cardClassNamein React,class/cardClassin Vue). - Full markup override via
renderCard/render(React) or slots (Vue).
data-rankhiker hooks
Both adapters emit the same data-rankhiker attribute names on their default markup, so one stylesheet styles React and Vue identically.
| Selector | Element |
|---|---|
[data-rankhiker="blog-list"] | Grid container in . |
[data-rankhiker="blog-card"] | Each card in the list. |
[data-rankhiker="meta"] | Author / reading-time / date row. |
[data-rankhiker="blog-post"] | wrapper. |
[data-rankhiker="takeaways"] | Key Takeaways aside. |
[data-rankhiker="content"] | Article body div (rendered HTML). |
[data-rankhiker="faq"] | FAQ section. |
A clean, responsive blog built purely on the hooks above:
/ List grid /
[data-rankhiker="blog-list"] {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.5rem;
}
/ Cards /
[data-rankhiker="blog-card"] {
border: 1px solid #e5e7eb;
border-radius: 12px;
overflow: hidden;
transition: box-shadow 0.2s;
}
[data-rankhiker="blog-card"]:hover {
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}
[data-rankhiker="blog-card"] img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}
[data-rankhiker="blog-card"] h2 {
font-size: 1.125rem;
margin: 0.75rem 1rem 0.25rem;
}
[data-rankhiker="blog-card"] p {
margin: 0 1rem 1rem;
color: #6b7280;
}
/ Meta row /
[data-rankhiker="meta"] {
display: flex;
gap: 0.75rem;
font-size: 0.8125rem;
color: #9ca3af;
}
/ Single post /
[data-rankhiker="blog-post"] {
max-width: 720px;
margin: 0 auto;
}
/ Article prose /
[data-rankhiker="content"] {
line-height: 1.7;
}
[data-rankhiker="content"] h2 {
margin-top: 2rem;
}
[data-rankhiker="content"] img {
max-width: 100%;
border-radius: 8px;
}
/ Key takeaways /
[data-rankhiker="takeaways"] {
background: #f9fafb;
border-left: 4px solid #8b5cf6;
padding: 1rem 1.25rem;
border-radius: 0 8px 8px 0;
}
/ FAQ /
[data-rankhiker="faq"] details {
border-bottom: 1px solid #e5e7eb;
padding: 0.75rem 0;
}
[data-rankhiker="faq"] summary {
cursor: pointer;
font-weight: 600;
}
Class props
For utility frameworks like Tailwind, pass classes directly instead of writing global CSS.
React:
<BlogList className="grid gap-6 sm:grid-cols-2" cardClassName="rounded-xl border" />
<BlogPost slug={slug} className="prose mx-auto" />
Vue:
<BlogList class="grid gap-6 sm:grid-cols-2" card-class="rounded-xl border" />
<BlogPost :slug="slug" class="prose mx-auto" />
Full markup override
When the default markup is not enough, replace it entirely.
React, via renderCard and render:
<BlogList
renderCard={(post) => (
<a key={post.id} href={/blog/${post.slug}} className="my-card">
<h3>{post.title}</h3>
</a>
)}
/>
<BlogPost
slug={slug}
render={(post) => (
<article className="my-article">
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content }} />
</article>
)}
/>
Vue, via the card slot and the default slot:
<BlogList>
<template #card="{ post }">
<a :href="/blog/${post.slug}" class="my-card">
<h3>{{ post.title }}</h3>
</a>
</template>
</BlogList>
<BlogPost :slug="slug">
<template #default="{ post }">
<article class="my-article">
<h1>{{ post.title }}</h1>
<div v-html="post.content" />
</article>
</template>
</BlogPost>
When you fully override markup, the data-rankhiker hooks are not emitted, so style those custom elements with your own classes.
Was this article helpful?