<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://csswitch.github.io/jekyll-vaporwave-theme/feed.xml" rel="self" type="application/atom+xml" /><link href="https://csswitch.github.io/jekyll-vaporwave-theme/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-05-12T20:27:52+00:00</updated><id>https://csswitch.github.io/jekyll-vaporwave-theme/feed.xml</id><title type="html">Vaporwave Theme Demo</title><subtitle>Retro 80s/90s aesthetic Jekyll theme — pastel gradients, synthwave vibes, chrome serif typography</subtitle><author><name>csswitch</name></author><entry><title type="html">CSS Techniques Behind Vaporwave: Gradients, Glitch &amp;amp; Synthwave Grid</title><link href="https://csswitch.github.io/jekyll-vaporwave-theme/2024/01/22/css-techniques-vaporwave/" rel="alternate" type="text/html" title="CSS Techniques Behind Vaporwave: Gradients, Glitch &amp;amp; Synthwave Grid" /><published>2024-01-22T09:00:00+00:00</published><updated>2024-01-22T09:00:00+00:00</updated><id>https://csswitch.github.io/jekyll-vaporwave-theme/2024/01/22/css-techniques-vaporwave</id><content type="html" xml:base="https://csswitch.github.io/jekyll-vaporwave-theme/2024/01/22/css-techniques-vaporwave/"><![CDATA[<p>Vaporwave Theme is built almost entirely on CSS — no canvas, no WebGL, no heavy JS libraries. This post breaks down the four core techniques that create the aesthetic.</p>

<h2 id="1-gradient-text-with--webkit-background-clip">1. Gradient Text with <code class="language-plaintext highlighter-rouge">-webkit-background-clip</code></h2>

<p>The headline gradient fill uses a WebKit-era property that’s now in the CSS spec:</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">h1</span> <span class="p">{</span>
  <span class="nl">background</span><span class="p">:</span> <span class="n">linear-gradient</span><span class="p">(</span><span class="m">90deg</span><span class="p">,</span> <span class="m">#ff71ce</span><span class="p">,</span> <span class="m">#01cdfe</span><span class="p">);</span>
  <span class="nl">-webkit-background-clip</span><span class="p">:</span> <span class="nb">text</span><span class="p">;</span>
  <span class="nl">-webkit-text-fill-color</span><span class="p">:</span> <span class="nb">transparent</span><span class="p">;</span>
  <span class="nl">background-clip</span><span class="p">:</span> <span class="nb">text</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The trick: set <code class="language-plaintext highlighter-rouge">color</code> to <code class="language-plaintext highlighter-rouge">transparent</code> so the background bleeds through the text shape. The <code class="language-plaintext highlighter-rouge">background-clip: text</code> (without prefix) is the spec version; <code class="language-plaintext highlighter-rouge">-webkit-background-clip</code> is the one that actually works in Chrome and Safari. Firefox needs both.</p>

<p><strong>Important:</strong> <code class="language-plaintext highlighter-rouge">text-fill-color</code> (not <code class="language-plaintext highlighter-rouge">color</code>) must be transparent — <code class="language-plaintext highlighter-rouge">color: transparent</code> alone doesn’t work in Safari.</p>

<h2 id="2-synthwave-perspective-grid">2. Synthwave Perspective Grid</h2>

<p>The animated grid in the hero is pure CSS:</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">.vp-hero</span><span class="nd">::before</span> <span class="p">{</span>
  <span class="nl">content</span><span class="p">:</span> <span class="s2">''</span><span class="p">;</span>
  <span class="nl">position</span><span class="p">:</span> <span class="nb">absolute</span><span class="p">;</span>
  <span class="nl">bottom</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span> <span class="nl">left</span><span class="p">:</span> <span class="m">-50%</span><span class="p">;</span> <span class="nl">right</span><span class="p">:</span> <span class="m">-50%</span><span class="p">;</span>
  <span class="nl">height</span><span class="p">:</span> <span class="m">60%</span><span class="p">;</span>
  <span class="nl">background-image</span><span class="p">:</span>
    <span class="n">linear-gradient</span><span class="p">(</span><span class="n">rgba</span><span class="p">(</span><span class="m">1</span><span class="p">,</span><span class="m">205</span><span class="p">,</span><span class="m">254</span><span class="p">,</span><span class="m">0.2</span><span class="p">)</span> <span class="m">1px</span><span class="p">,</span> <span class="nb">transparent</span> <span class="m">1px</span><span class="p">),</span>
    <span class="n">linear-gradient</span><span class="p">(</span><span class="m">90deg</span><span class="p">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">255</span><span class="p">,</span><span class="m">113</span><span class="p">,</span><span class="m">206</span><span class="p">,</span><span class="m">0.2</span><span class="p">)</span> <span class="m">1px</span><span class="p">,</span> <span class="nb">transparent</span> <span class="m">1px</span><span class="p">);</span>
  <span class="nl">background-size</span><span class="p">:</span> <span class="m">80px</span> <span class="m">80px</span><span class="p">;</span>
  <span class="nl">transform</span><span class="p">:</span> <span class="n">perspective</span><span class="p">(</span><span class="m">300px</span><span class="p">)</span> <span class="n">rotateX</span><span class="p">(</span><span class="m">60deg</span><span class="p">);</span>
  <span class="nl">transform-origin</span><span class="p">:</span> <span class="nb">bottom</span> <span class="nb">center</span><span class="p">;</span>
  <span class="nl">animation</span><span class="p">:</span> <span class="n">grid-scroll</span> <span class="m">3s</span> <span class="n">linear</span> <span class="n">infinite</span><span class="p">;</span>
  <span class="py">mask-image</span><span class="p">:</span> <span class="n">linear-gradient</span><span class="p">(</span><span class="n">to</span> <span class="nb">top</span><span class="p">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0.5</span><span class="p">)</span> <span class="m">0%</span><span class="p">,</span> <span class="nb">transparent</span> <span class="m">100%</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">@keyframes</span> <span class="n">grid-scroll</span> <span class="p">{</span>
  <span class="nt">from</span> <span class="p">{</span> <span class="py">background-position-y</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span> <span class="p">}</span>
  <span class="nt">to</span>   <span class="p">{</span> <span class="py">background-position-y</span><span class="p">:</span> <span class="m">80px</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">transform: perspective(300px) rotateX(60deg)</code> is what tilts the flat grid into the 3D floor illusion. <code class="language-plaintext highlighter-rouge">transform-origin: bottom center</code> anchors the rotation at the floor. The <code class="language-plaintext highlighter-rouge">mask-image</code> fades the grid to nothing at the top, so it blends into the hero background.</p>

<p>The animation (<code class="language-plaintext highlighter-rouge">background-position-y</code>) scrolls the grid towards the viewer — <code class="language-plaintext highlighter-rouge">80px</code> matches <code class="language-plaintext highlighter-rouge">background-size</code>, so it loops seamlessly.</p>

<h2 id="3-glitch-effect-with-clip-path">3. Glitch Effect with <code class="language-plaintext highlighter-rouge">clip-path</code></h2>

<p>The glitch on post title hover uses two pseudo-elements that reveal different clipped slices at staggered offsets:</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">@keyframes</span> <span class="n">glitch-1</span> <span class="p">{</span>
  <span class="err">0</span><span class="o">%</span>   <span class="p">{</span> <span class="nl">clip-path</span><span class="p">:</span> <span class="n">polygon</span><span class="p">(</span><span class="m">0</span> <span class="m">15%</span><span class="p">,</span> <span class="m">100%</span> <span class="m">15%</span><span class="p">,</span> <span class="m">100%</span> <span class="m">30%</span><span class="p">,</span> <span class="m">0</span> <span class="m">30%</span><span class="p">);</span>
         <span class="nl">transform</span><span class="p">:</span> <span class="n">translate</span><span class="p">(</span><span class="m">-3px</span><span class="p">,</span> <span class="m">0</span><span class="p">);</span> <span class="p">}</span>
  <span class="err">25</span><span class="o">%</span>  <span class="p">{</span> <span class="nl">clip-path</span><span class="p">:</span> <span class="n">polygon</span><span class="p">(</span><span class="m">0</span> <span class="m">60%</span><span class="p">,</span> <span class="m">100%</span> <span class="m">60%</span><span class="p">,</span> <span class="m">100%</span> <span class="m">75%</span><span class="p">,</span> <span class="m">0</span> <span class="m">75%</span><span class="p">);</span>
         <span class="nl">transform</span><span class="p">:</span> <span class="n">translate</span><span class="p">(</span><span class="m">3px</span><span class="p">,</span> <span class="m">0</span><span class="p">);</span> <span class="p">}</span>
  <span class="err">100</span><span class="o">%</span> <span class="p">{</span> <span class="nl">clip-path</span><span class="p">:</span> <span class="n">polygon</span><span class="p">(</span><span class="m">0</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span> <span class="m">0</span><span class="p">);</span>
         <span class="nl">transform</span><span class="p">:</span> <span class="n">translate</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">);</span> <span class="p">}</span>
<span class="p">}</span>

<span class="nc">.glitch</span><span class="nd">::before</span> <span class="p">{</span>
  <span class="nl">content</span><span class="p">:</span> <span class="n">attr</span><span class="p">(</span><span class="n">data-text</span><span class="p">);</span>  <span class="c">/* text copied from JS */</span>
  <span class="nl">position</span><span class="p">:</span> <span class="nb">absolute</span><span class="p">;</span>
  <span class="nl">top</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span> <span class="nl">left</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span>
  <span class="nl">color</span><span class="p">:</span> <span class="m">#ff71ce</span><span class="p">;</span>
  <span class="nl">animation</span><span class="p">:</span> <span class="n">glitch-1</span> <span class="m">0.3s</span> <span class="n">steps</span><span class="p">(</span><span class="m">1</span><span class="p">)</span> <span class="n">forwards</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">steps(1)</code> is the key — it makes the animation jump instantly between keyframes instead of interpolating. That’s what produces the harsh digital glitch feel rather than a smooth transition.</p>

<p>JavaScript copies the text content into <code class="language-plaintext highlighter-rouge">data-text</code> so the pseudo-element can reference it with <code class="language-plaintext highlighter-rouge">attr(data-text)</code>.</p>

<h2 id="4-crt-scanlines">4. CRT Scanlines</h2>

<p>The subtle scanlines overlay is a <code class="language-plaintext highlighter-rouge">repeating-linear-gradient</code> on <code class="language-plaintext highlighter-rouge">body::after</code>:</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">body</span><span class="nd">::after</span> <span class="p">{</span>
  <span class="nl">content</span><span class="p">:</span> <span class="s2">''</span><span class="p">;</span>
  <span class="nl">position</span><span class="p">:</span> <span class="nb">fixed</span><span class="p">;</span>
  <span class="py">inset</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span>
  <span class="nl">background</span><span class="p">:</span> <span class="n">repeating-linear-gradient</span><span class="p">(</span>
    <span class="m">0deg</span><span class="p">,</span>
    <span class="nb">transparent</span><span class="p">,</span> <span class="nb">transparent</span> <span class="m">2px</span><span class="p">,</span>
    <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0.025</span><span class="p">)</span> <span class="m">2px</span><span class="p">,</span> <span class="n">rgba</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">0.025</span><span class="p">)</span> <span class="m">4px</span>
  <span class="p">);</span>
  <span class="nl">pointer-events</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
  <span class="nl">z-index</span><span class="p">:</span> <span class="m">9999</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">repeating-linear-gradient(0deg, ...)</code> draws horizontal bands — 2px transparent, 2px dark. This sits above everything (<code class="language-plaintext highlighter-rouge">z-index: 9999</code>) with <code class="language-plaintext highlighter-rouge">pointer-events: none</code> so it doesn’t block clicks. The opacity is deliberately low (<code class="language-plaintext highlighter-rouge">0.025</code>) so it reads as a texture rather than noise.</p>

<h2 id="putting-it-together">Putting It Together</h2>

<p>These four techniques combine to create the full aesthetic with under 150 lines of CSS. No images, no JS frameworks, no performance overhead — just geometry and color working together.</p>]]></content><author><name>csswitch</name></author><category term="css" /><category term="gradients" /><category term="animation" /><category term="design" /><category term="vaporwave" /><summary type="html"><![CDATA[A breakdown of the CSS techniques powering Vaporwave Theme — gradient text, perspective grid, glitch clip-path, and CRT scanlines.]]></summary></entry><entry><title type="html">Welcome to Vaporwave Theme</title><link href="https://csswitch.github.io/jekyll-vaporwave-theme/2024/01/15/welcome-to-vaporwave-theme/" rel="alternate" type="text/html" title="Welcome to Vaporwave Theme" /><published>2024-01-15T09:00:00+00:00</published><updated>2024-01-15T09:00:00+00:00</updated><id>https://csswitch.github.io/jekyll-vaporwave-theme/2024/01/15/welcome-to-vaporwave-theme</id><content type="html" xml:base="https://csswitch.github.io/jekyll-vaporwave-theme/2024/01/15/welcome-to-vaporwave-theme/"><![CDATA[<p>Vaporwave Theme is a Jekyll theme built for creators who want their blog to feel less like a tech article and more like a late-night drive through a neon-lit city from an alternate 1989. Hot pinks, electric cyans, soft violets. A synthwave grid hero. Serif headlines with gradient fills. Glitch hover effects that trigger on every post title.</p>

<h2 id="the-aesthetic">The Aesthetic</h2>

<p>Vaporwave as an art movement emerged in the early 2010s as a critique of hyper-commodified culture — pastel gradients, Japanese text fragments, Greek busts, Windows 95 interfaces reimagined as dreamscapes. As a visual aesthetic it combines:</p>

<ul>
  <li><strong>Pastel neons</strong> — hot pink, electric cyan, soft purple, pastel lemon</li>
  <li><strong>Retro typography</strong> — chrome serif (Playfair Display), monospace Space Mono</li>
  <li><strong>CRT nostalgia</strong> — scanlines, glitch effects, perspective grids</li>
  <li><strong>Dreamy darkness</strong> — deep purple/black backgrounds that make pastels pop</li>
</ul>

<h2 id="installing-the-theme">Installing the Theme</h2>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://github.com/csswitch/jekyll-vaporwave-theme.git my-site
<span class="nb">cd </span>my-site
bundle <span class="nb">install
</span>bundle <span class="nb">exec </span>jekyll serve
</code></pre></div></div>

<p>Visit <code class="language-plaintext highlighter-rouge">http://localhost:4000</code> — you’ll have the full vaporwave aesthetic running locally.</p>

<h2 id="configuration">Configuration</h2>

<p>Open <code class="language-plaintext highlighter-rouge">_config.yml</code> to customize:</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">My</span><span class="nv"> </span><span class="s">Blog"</span>
<span class="na">description</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Your</span><span class="nv"> </span><span class="s">tagline</span><span class="nv"> </span><span class="s">here"</span>

<span class="na">vaporwave</span><span class="pi">:</span>
  <span class="na">grid</span><span class="pi">:</span> <span class="no">true</span>          <span class="c1"># synthwave perspective grid on hero</span>
  <span class="na">scanlines</span><span class="pi">:</span> <span class="no">true</span>     <span class="c1"># CRT scanlines overlay</span>
  <span class="na">glitch</span><span class="pi">:</span> <span class="no">true</span>        <span class="c1"># glitch effect on post titles</span>
  <span class="na">gradient_text</span><span class="pi">:</span> <span class="no">true</span> <span class="c1"># gradient fills on headings</span>
  <span class="na">neon_border</span><span class="pi">:</span> <span class="no">true</span>   <span class="c1"># neon glow on card borders</span>
</code></pre></div></div>

<p>Each effect can be toggled independently. Turn off <code class="language-plaintext highlighter-rouge">scanlines</code> for a cleaner look, or keep <code class="language-plaintext highlighter-rouge">glitch: false</code> if you want the headers to stay still.</p>

<h2 id="typography-choices">Typography Choices</h2>

<p>The theme uses three Google Fonts:</p>

<table>
  <thead>
    <tr>
      <th>Font</th>
      <th>Usage</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Playfair Display</td>
      <td>Headlines — serif with high contrast strokes</td>
    </tr>
    <tr>
      <td>Space Grotesk</td>
      <td>Body text — geometric sans, very readable</td>
    </tr>
    <tr>
      <td>Space Mono</td>
      <td>Code, dates, tags — chunky monospace</td>
    </tr>
  </tbody>
</table>

<p>The Playfair Display headlines get a CSS gradient fill via <code class="language-plaintext highlighter-rouge">-webkit-background-clip: text</code>. This works in all modern browsers and degrades gracefully (shows solid pink) in older ones.</p>

<h2 id="writing-your-first-post">Writing Your First Post</h2>

<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">---</span>
<span class="na">layout</span><span class="pi">:</span> <span class="s">post</span>
<span class="na">title</span><span class="pi">:</span> <span class="s2">"</span><span class="s">My</span><span class="nv"> </span><span class="s">Post</span><span class="nv"> </span><span class="s">Title"</span>
<span class="na">date</span><span class="pi">:</span> <span class="s">2024-01-15</span>
<span class="na">tags</span><span class="pi">:</span> <span class="pi">[</span><span class="nv">vaporwave</span><span class="pi">,</span> <span class="nv">design</span><span class="pi">,</span> <span class="nv">css</span><span class="pi">]</span>
<span class="nn">---</span>

Content goes here...
</code></pre></div></div>

<p>Tags appear as neon pills in the post header and in the full tag cloud at <code class="language-plaintext highlighter-rouge">/tags/</code>. The home page hero rotates the 6 most recent posts in a responsive card grid.</p>]]></content><author><name>csswitch</name></author><category term="jekyll" /><category term="theme" /><category term="vaporwave" /><category term="retro" /><category term="aesthetics" /><summary type="html"><![CDATA[Vaporwave Theme brings the iconic 80s/90s retro aesthetic to your Jekyll blog — pastel neon gradients, synthwave grid, and glitch typography.]]></summary></entry></feed>