CSS docs

Learn the few classes you need, copy a recipe, then go wild. Looking for a ready-made look? Browse the templates.

CSS docs

How it works

  • Your CSS comes last. It loads after our base styles, so a rule with the same selector wins. If something doesn't change, make your selector more specific or add !important.
  • Allowed: any CSS. That includes @import (Google Fonts), @keyframes, ::before/::after, 3D transforms, filters, and images from any https URL.
  • Blocked: JavaScript. Your page runs zero scripts, which keeps visitors safe.
  • Limit: 50 KB of CSS. That's a lot.

Page structure

<body class="zbr-page layout-card cols-2">
  <video class="zbr-bg-video">            <!-- only with a video background -->
  <div class="zbr-space">
    <aside class="zbr-col zbr-side">
      <section class="zbr-card zbr-box zbr-box-profile">
        <div class="zbr-box-body">
          <img class="zbr-avatar">
          <h1 class="zbr-name">yourname</h1>
          <p class="zbr-bio">your bio</p>
        </div>
      </section>
      <section class="zbr-card zbr-box zbr-box-links">
        <h2 class="zbr-box-title">Links</h2>
        <div class="zbr-box-body">
          <nav class="zbr-links"><a class="zbr-link">Discord</a> …</nav>
        </div>
      </section>
      <div class="zbr-views">👁 1,337 views</div>
    </aside>
    <main class="zbr-col zbr-main">
      <section class="zbr-card zbr-box zbr-box-text"> … </section>
      <section class="zbr-card zbr-box zbr-box-friends" id="friends"> … </section>
      <section class="zbr-card zbr-box zbr-box-wall" id="wall"> … </section>
    </main>
  </div>
</body>

<!-- 1 column: body.cols-1 and a single <main class="zbr-card">
     with the avatar, name, bio, links… inside, then the other blocks -->

Classes

body.zbr-pageThe whole page. Also has .layout-card or .layout-minimal.
.zbr-bg-videoThe background video (only when you use one).
.zbr-cardThe main box (1 column), or every block (2 columns). Style it once, it applies everywhere.
.zbr-avatarYour profile picture.
.zbr-nameYour display name.
.zbr-bioYour bio text.
.zbr-linksThe container around all links.
.zbr-linkEach link button. Try :nth-child(even) for alternating styles.
.zbr-viewsThe view counter.
.zbr-spaceThe 2-column grid (body also gets .cols-2; 1 column gets .cols-1).
.zbr-side, .zbr-mainThe side and main columns.
.zbr-boxEvery block. In 2 columns it is also a .zbr-card.
.zbr-box-titleA block heading (About me, Friends, Comments…).
.zbr-box-profile, .zbr-box-text …One kind of block: .zbr-box-details, -links, -text, -table, -friends, -wall, -gallery, -playlist, -html.
.zbr-friendEach friend in Friends (img or .zbr-noavatar, then the name in <b>).
.zbr-commentOne wall comment (.zbr-comment-meta, .zbr-comment-body).
.zbr-wall-form, .zbr-sendThe one-line comment field and its send icon button.
.zbr-tableLabel/value tables (details, interests).

CSS variables

These are set from the editor's color and font fields. Override them in :root.

--accentAccent color (borders, link tint).
--textText color.
--cardCard background.
--fontFont family for the whole page.

Gotchas

  • Don't put transform, perspective or filter on the body. It turns position: fixed into "fixed to the body", so full-screen layers stop covering the screen. Put them on .zbr-card instead.
  • Big decorative layers can create scrollbars. Add html, body { overflow: clip; } to keep the page exactly screen-sized.
  • @import must be the first line of your CSS, or the browser ignores it.
  • Free pseudo-elements: html::before, html::after, body::before and body::after are all unused. Great for overlays and banners.

Tutorials

Small recipes. Copy one into the Custom CSS box in the editor.

1 Use any Google Font

Pick a font on fonts.google.com, then import it at the very top of your CSS and point --font at it.

@import url('https://fonts.googleapis.com/css2?family=Bungee&display=block');

:root { --font: 'Bungee', sans-serif; }

2 Animated gradient background

Make the gradient bigger than the screen, then slide it around with a keyframe animation.

body.zbr-page {
  background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
  background-size: 400% 400%;
  animation: shift 10s ease infinite;
}
@keyframes shift {
  50% { background-position: 100% 50%; }
}

3 Glowing links on hover

box-shadow with a big blur radius and your accent color makes things glow.

.zbr-link { transition: box-shadow .2s, transform .2s; }
.zbr-link:hover {
  box-shadow: 0 0 12px var(--accent), 0 0 32px var(--accent);
  transform: scale(1.03);
}

4 Spinning rainbow avatar ring

A conic-gradient border plus a rotation animation. Upload an avatar first to see it.

.zbr-avatar {
  border: 4px solid transparent;
  background: conic-gradient(red, orange, yellow, lime, cyan, blue, magenta, red) border-box;
  animation: spin 3s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

5 Add text without HTML

::before and ::after let you add text, emoji or shapes anywhere. Here we add a status line and restyle the view counter.

.zbr-name::after { content: ' ✔'; color: var(--accent); }
.zbr-card::before { content: '🟢 online now'; font-size: .8rem; opacity: .7; }
.zbr-views::before { content: 'profile visits: '; }

6 Custom emoji cursor

cursor accepts an image URL. An inline SVG with an emoji works without uploading anything.

body.zbr-page {
  cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32'><text y='26' font-size='26'>✨</text></svg>") 16 16, auto;
}

Make a template with ChatGPT

No CSS skills? Let ChatGPT (or any AI chat) write it for you. Four steps and you're done.

  1. 1

    Copy the prompt

    It already explains how zbr.lat pages are built, so the AI knows which classes to style.

  2. 2

    Describe your style

    Paste it into ChatGPT and replace the last line with the look you want. Be specific: colors, fonts, mood, references. Example: "dark vaporwave, pink and cyan neon, pixel font, glowing link buttons".

  3. 3

    Paste the CSS

    Copy the CSS it gives you into the Custom CSS box in the editor and save. Not quite right? Tell the AI what to change ("links are too small", "less purple") and paste again.

  4. 4

    Share it (optional)

    Proud of it? Publish it as a template so others can use it too.

The prompt

You are a CSS expert. Write custom CSS for my bio-link page on zbr.lat.

Rules:
- Only CSS. No HTML, no JavaScript (scripts are blocked).
- My CSS loads after the site's base styles; use more specific selectors or !important if a rule doesn't apply.
- @import (e.g. Google Fonts) must be the very first line.
- Max 50 KB. Images only from https URLs.
- Don't put transform, perspective or filter on body (it breaks position: fixed). Put them on .zbr-card.
- Add html, body { overflow: clip; } if big decorative layers create scrollbars.
- html::before, html::after, body::before and body::after are free to use for overlays.
- Style both 1 column (body.cols-1) and 2 columns (body.cols-2), and make it look good on phones.

Page structure:
<body class="zbr-page layout-card cols-2">
  <video class="zbr-bg-video">            <!-- only with a video background -->
  <div class="zbr-space">
    <aside class="zbr-col zbr-side">
      <section class="zbr-card zbr-box zbr-box-profile">
        <div class="zbr-box-body">
          <img class="zbr-avatar">
          <h1 class="zbr-name">yourname</h1>
          <p class="zbr-bio">your bio</p>
        </div>
      </section>
      <section class="zbr-card zbr-box zbr-box-links">
        <h2 class="zbr-box-title">Links</h2>
        <div class="zbr-box-body">
          <nav class="zbr-links"><a class="zbr-link">Discord</a> …</nav>
        </div>
      </section>
      <div class="zbr-views">👁 1,337 views</div>
    </aside>
    <main class="zbr-col zbr-main">
      <section class="zbr-card zbr-box zbr-box-text"> … </section>
      <section class="zbr-card zbr-box zbr-box-friends" id="friends"> … </section>
      <section class="zbr-card zbr-box zbr-box-wall" id="wall"> … </section>
    </main>
  </div>
</body>

<!-- 1 column: body.cols-1 and a single <main class="zbr-card">
     with the avatar, name, bio, links… inside, then the other blocks -->

Main classes:
- body.zbr-page: The whole page. Also has .layout-card or .layout-minimal.
- .zbr-bg-video: The background video (only when you use one).
- .zbr-card: The main box (1 column), or every block (2 columns). Style it once, it applies everywhere.
- .zbr-avatar: Your profile picture.
- .zbr-name: Your display name.
- .zbr-bio: Your bio text.
- .zbr-links: The container around all links.
- .zbr-link: Each link button. Try :nth-child(even) for alternating styles.
- .zbr-views: The view counter.
- .zbr-space: The 2-column grid (body also gets .cols-2; 1 column gets .cols-1).
- .zbr-side, .zbr-main: The side and main columns.
- .zbr-box: Every block. In 2 columns it is also a .zbr-card.
- .zbr-box-title: A block heading (About me, Friends, Comments…).
- .zbr-box-profile, .zbr-box-text …: One kind of block: .zbr-box-details, -links, -text, -table, -friends, -wall, -gallery, -playlist, -html.
- .zbr-friend: Each friend in Friends (img or .zbr-noavatar, then the name in <b>).
- .zbr-comment: One wall comment (.zbr-comment-meta, .zbr-comment-body).
- .zbr-wall-form, .zbr-send: The one-line comment field and its send icon button.
- .zbr-table: Label/value tables (details, interests).

CSS variables (set from the editor, override in :root): --accent, --text, --card, --font.

Reply with a single CSS code block.

The style I want: [DESCRIBE YOUR STYLE HERE]

Tips: ask for one change at a time; if something breaks, paste the CSS back and ask the AI to fix it; images must be https links.