SASS

Introduction

Modern frontend development offers two powerful styling approaches: Tailwind CSS provides utility classes for rapid UI construction, while Sass (SCSS syntax) extends CSS with variables, mixins, and partials that compile into standard CSS. This lesson demonstrates how both tools integrate into a Jekyll project. You’ll explore a small interactive Tailwind playground and complete a free-response question about choosing between utilities and abstractions.

What Tailwind and Sass Do

  • Tailwind CSS: A utility-first framework that applies styles via pre-defined classes like p-4, bg-blue-500, rounded-lg. Speeds up prototyping and keeps markup colocated with styles.
  • Sass (SCSS): A CSS preprocessor that adds variables ($primary-color), nesting, mixins, and file imports. Compiles to regular CSS at build time.
  • When to use: Use Tailwind for rapid component styling and responsive layouts. Use Sass for design tokens, reusable mixins, and complex theme logic that spans multiple pages.

Minimal Setup in Jekyll

A) Tailwind Quick Demo via CDN

For experimentation, load Tailwind via CDN (not recommended for production):

<script src="https://cdn.tailwindcss.com"></script>

B) Production Tailwind Build

Install Tailwind and PostCSS:

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init

tailwind.config.js

module.exports = {
  content: ['./_site/**/*.html', './**/*.md', './**/*.html'],
  theme: { extend: {} },
  plugins: [],
}

postcss.config.js

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  }
}

assets/css/tailwind.css

@tailwind base;
@tailwind components;
@tailwind utilities;

package.json scripts

{
  "scripts": {
    "build:css": "tailwindcss -i ./assets/css/tailwind.css -o ./_site/assets/css/tw.css --minify"
  }
}

Link in your layout:

<link rel="stylesheet" href="/assets/css/tw.css">

C) Sass Structure in Jekyll

Create _sass/ folder for partials. Jekyll compiles any .scss file in assets/css/ that has YAML front matter.

_sass/_variables.scss

$primary: #2563eb;
$spacing: 1rem;

_sass/_mixins.scss

@mixin card-shadow {
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

assets/css/main.scss

---
---
@use '../_sass/variables' as *;
@use '../_sass/mixins' as *;

body {
  font-family: system-ui, sans-serif;
  color: $primary;
}

.card {
  padding: $spacing;
  @include card-shadow;
}

Link in your layout:

<link rel="stylesheet" href="/assets/css/main.css">

Tiny Interactive Demo (Tailwind Playground)

Tailwind Utility Playground

Adjust the settings and click Apply to see Tailwind classes in action.

Sample Card

This card updates with your chosen Tailwind utilities.

What to Use When

Use Tailwind when:

  • Building UI components quickly with responsive design
  • Prototyping layouts without writing custom CSS
  • Keeping styles scoped to individual elements

Use Sass when:

  • Managing design tokens (colors, spacing) across the entire site
  • Creating reusable mixins for complex patterns (animations, shadows)
  • Organizing styles into modular partials for maintainability

Quick Knowledge Check

What's the main difference between Tailwind and Sass? Tailwind provides pre-built utility classes you apply directly in HTML. Sass extends CSS with features like variables and mixins that compile to standard CSS.
Why use Sass variables instead of Tailwind's built-in colors? Sass variables centralize theme values in one place and can be dynamically computed or reused in complex calculations that Tailwind's fixed palette doesn't support.
Can you use Tailwind and Sass together? Yes. Use Tailwind for component utilities and Sass for global styles, theme variables, and custom mixins. Both outputs link separately in your Jekyll layout.

Student Free Response (FRQ) — Tailwind + Sass

Prompt: Write 4–6 sentences explaining when to choose Tailwind utilities versus Sass abstractions in a Jekyll project. Describe how tw.css (Tailwind output) and main.css (Sass output) work together in the final site. Provide one example best suited for Tailwind utilities and one example best suited for a Sass mixin.

Summary

  • Tailwind CSS accelerates UI development with utility classes; production requires a build step to purge unused styles.
  • Sass organizes styles with variables, mixins, and partials; Jekyll compiles .scss files with front matter into .css.
  • Jekyll outputs: tw.css (Tailwind) and main.css (Sass) link independently in your layout for complementary styling.
  • Best practice: Use Tailwind for component-level styling and Sass for theme management and reusable abstractions.

Interactive Demo JavaScript

Tailwind Playground Script

(function() {
  const selPadding = document.getElementById('sel-padding');
  const selRadius = document.getElementById('sel-radius');
  const selTone = document.getElementById('sel-tone');
  const btnApply = document.getElementById('btn-apply');
  const demoCard = document.getElementById('demo-card');

  btnApply.addEventListener('click', () => {
    const padding = selPadding.value;
    const radius = selRadius.value;
    const tone = selTone.value;
    demoCard.className = `${padding} ${radius} ${tone}`;
    demoCard.style.border = '1px solid #4b5563';
  });
})();

Form Submission Handler

import { javaURI } from '/assets/js/api/config.js';

document.addEventListener("DOMContentLoaded", () => {
  const submitBtn = document.getElementById("submitBtn");
  const nameInput = document.getElementById("name");
  const responseInput = document.getElementById("response");
  const messageDiv = document.getElementById("message");

  submitBtn.addEventListener("click", async () => {
    const name = nameInput.value.trim();
    const response = responseInput.value.trim();

    if (!name || !response) {
      messageDiv.textContent = "Please fill in both fields.";
      messageDiv.style.color = "red";
      return;
    }

    try {
      const res = await fetch(`${javaURI}/api/responses`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name, response })
      });

      if (res.ok) {
        const data = await res.json();
        messageDiv.textContent = `✅ Response saved! (ID: ${data.id})`;
        messageDiv.style.color = "green";
        responseInput.value = "";
      } else {
        messageDiv.textContent = "⚠️ Error submitting response.";
        messageDiv.style.color = "red";
      }
    } catch (err) {
      messageDiv.textContent = "❌ Could not connect to server.";
      messageDiv.style.color = "red";
    }
  });
});