\n

Hang up… please wait, we're loading

🎨 Stage 2 of 7

Frontend Dev

CSS magic, JavaScript power, modern layouts, animations, Three.js 3D, and React — the full frontend toolkit.

~6 hours
Beginner → Intermediate
High Impact
Inspector Mode Active Nexray Stage 2: Frontend Dev — your interactive learning companion
Pro Tip

Open DevTools (F12) to inspect any website's HTML & CSS.

🎨 CSS Fundamentals

style.cssbody {font-family: Inter;background: #fafafa;color: #ffffff;}

CSS Gives Your Site Its Look

CSS (Cascading Style Sheets) controls how HTML elements appear on screen — every color, font, spacing rule, and animation is powered by CSS.

  • Selectors target HTML elements
  • Properties define visual appearance
  • Responsive design adapts to any screen

CSS (Cascading Style Sheets) controls how HTML looks. You write selectors to target elements and declarations to style them.

CSS
/* Selector { property: value; } */

/* Element selector */
h1 {
  color: #0038FF;
  font-size: 2.5rem;
  font-weight: 900;
}

/* Class selector (reusable) */
.card {
  background: #1a1a2e;
  border-radius: 12px;
  padding: 24px;
}

/* ID selector (unique, use sparingly) */
#hero {
  min-height: 100vh;
}

/* Descendant: p inside .card */
.card p { color: #94a3b8; }

/* Pseudo-class: on hover */
.btn:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 30px rgba(249,115,22,0.4);
}

/* Pseudo-element: first letter */
p::first-letter {
  font-size: 2em;
  color: #0038FF;
}

The Box Model

Every HTML element is a rectangular box. Understanding the box model is fundamental to controlling spacing and sizing.

margin
border
padding
content (width × height)
CSS
.box {
  /* Always use border-box! It makes width include padding+border */
  box-sizing: border-box;

  width: 300px;
  height: 200px;

  /* Padding: space INSIDE the border */
  padding: 24px;          /* all sides */
  padding: 16px 24px;    /* top/bottom left/right */
  padding-top: 12px;    /* individual side */

  /* Border */
  border: 2px solid #0038FF;
  border-radius: 12px;

  /* Margin: space OUTSIDE the border */
  margin: 0 auto;       /* center horizontally */
}

📐 Flexbox Layout

flex:1flex:2flex:1

Flexbox: 1D Flexible Layouts

Flexbox makes it effortless to align items in a row or column. Think of it as a smart container that automatically distributes space between elements.

  • justify-content aligns on main axis
  • align-items aligns on cross axis
  • flex-grow lets items share space

Flexbox is a 1D layout system — you arrange items in a row or column. It's the most used layout tool in modern web dev.

CSS — Flexbox Cheatsheet
.container {
  display: flex;

  /* Direction */
  flex-direction: row;           /* → default, left to right */
  flex-direction: column;        /* ↓ top to bottom */

  /* Alignment on MAIN axis (row = horizontal) */
  justify-content: flex-start;  /* pack to start */
  justify-content: center;      /* center */
  justify-content: space-between;/* spread out */
  justify-content: space-around; /* equal spacing */

  /* Alignment on CROSS axis (row = vertical) */
  align-items: stretch;        /* fill height (default) */
  align-items: center;         /* vertically center */
  align-items: flex-end;       /* align to bottom */

  /* Gap between items */
  gap: 16px;
  flex-wrap: wrap;             /* wrap to next line */
}

.item {
  flex: 1;                     /* grow to fill space */
  flex: 0 0 200px;            /* fixed 200px, no grow/shrink */
}

/* Common pattern: center anything perfectly */
.center-everything {
  display: flex;
  align-items: center;
  justify-content: center;
}

🔲 CSS Grid

CSS Grid is a 2D layout system — rows AND columns. Perfect for page layouts, card grids, and complex designs.

CSS — Grid Cheatsheet
.grid {
  display: grid;

  /* Define columns */
  grid-template-columns: 1fr 1fr 1fr;     /* 3 equal columns */
  grid-template-columns: repeat(3, 1fr); /* same */
  grid-template-columns: 250px 1fr;      /* sidebar + content */

  /* Auto-fit responsive grid (NO media queries needed!) */
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));

  gap: 24px;
}

/* Item spanning multiple columns/rows */
.featured {
  grid-column: 1 / 3;   /* span columns 1 to 3 */
  grid-row: 1 / 2;       /* row 1 */
}

/* Named grid areas — super readable! */
.layout {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
  grid-template-columns: 240px 1fr;
}
header { grid-area: header; }
aside  { grid-area: sidebar; }
main   { grid-area: main; }
footer { grid-area: footer; }

Responsive Design

Your site must look great on phones, tablets, and desktops. Use media queries to apply different styles at different screen sizes.

CSS — Mobile-First Responsive
/* Mobile first: default styles = mobile */
.grid {
  display: grid;
  grid-template-columns: 1fr; /* single column on mobile */
  gap: 16px;
}

/* Tablet: 768px and up */
@media (min-width: 768px) {
  .grid {
    grid-template-columns: repeat(2, 1fr);
  }
  h1 { font-size: 3rem; }
}

/* Desktop: 1024px and up */
@media (min-width: 1024px) {
  .grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* Fluid typography with clamp() — no media queries! */
h1 {
  /* clamp(min, preferred, max) */
  font-size: clamp(2rem, 5vw, 5rem);
}

/* Prefer clamp() over media queries for font-size — 2026 best practice */

🎛️ CSS Variables & Theming

CSS custom properties (variables) let you define values once, use everywhere. Essential for theming and dark mode.

CSS — Variables + Dark Mode
/* Define variables on :root (global scope) */
:root {
  --color-bg: #ffffff;
  --color-text: #0f0f0f;
  --color-accent: #0038FF;
  --radius: 12px;
  --spacing: 24px;
}

/* Dark mode — triggered by OS preference */
@media (prefers-color-scheme: dark) {
  :root {
    --color-bg: #0a0a0f;
    --color-text: #f8fafc;
  }
}

/* Use variables */
body {
  background: var(--color-bg);
  color: var(--color-text);
}

.card {
  border-radius: var(--radius);
  padding: var(--spacing);
  border: 1px solid var(--color-accent);
}

/* Override variables locally */
.dark-card {
  --color-bg: #1a1a2e;
  background: var(--color-bg);
}

CSS Animations & Transitions

Smooth animations transform a static site into something that feels alive. Here are the key techniques:

CSS — Animations
/* === TRANSITIONS === */
/* Simple: smoothly animate property changes */
.btn {
  background: #0038FF;
  transition: all 250ms ease;
}
.btn:hover {
  background: #0038FF;
  transform: translateY(-4px) scale(1.03);
  box-shadow: 0 20px 40px rgba(249,115,22,0.4);
}

/* === KEYFRAME ANIMATIONS === */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(-12px); }
}

@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(249,115,22,0.4); }
  50%       { box-shadow: 0 0 0 15px rgba(249,115,22,0); }
}

/* Apply animations */
.hero-title {
  animation: fadeInUp 0.6s ease 0.2s both;
           /* name  duration timing delay fill */
}

.float-card { animation: float 4s ease-in-out infinite; }
.cta-btn    { animation: pulse 2s ease infinite; }

🪟 Glassmorphism UI (2026 Trend)

Glassmorphism creates a frosted-glass effect — one of the most popular design trends. Here's the exact recipe:

CSS — Glassmorphism
/* Step 1: Your page needs a colorful background */
body {
  background: linear-gradient(135deg, #0a0a0f, #1a0a00);
  /* Or use an image: background-image: url(bg.jpg); */
}

/* Step 2: The glass card */
.glass {
  /* Semi-transparent white background */
  background: rgba(255, 255, 255, 0.06);

  /* The KEY ingredient: backdrop blur */
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px); /* Safari */

  /* Subtle border for the glass edge */
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 20px;

  /* Soft shadow */
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.3),
    inset 0 1px 0 rgba(255,255,255,0.1);

  padding: 32px;
}

/* Orange accent glass variation */
.glass-orange {
  background: rgba(249, 115, 22, 0.08);
  border-color: rgba(249, 115, 22, 0.25);
  backdrop-filter: blur(20px);
  box-shadow: 0 0 40px rgba(249,115,22,0.15);
}

JavaScript Essentials

JavaScript makes websites interactive. It runs in the browser and can change HTML, respond to user events, and fetch data from servers.

JavaScript — Core Concepts
// === Variables ===
const name = 'Alice';          // immutable reference
let   count = 0;               // mutable
// Never use var in modern JS

// === Functions ===
// Traditional
function greet(name) {
  return `Hello, ${name}! 👋`;
}

// Arrow function (preferred in 2026)
const greet = (name) => `Hello, ${name}!`;

// === Arrays ===
const skills = ['HTML', 'CSS', 'JS'];
skills.push('React');           // add to end
skills.map(s => s.toLowerCase()); // transform each item
skills.filter(s => s !== 'CSS'); // filter items

// === Objects ===
const user = {
  name: 'Alice',
  age: 22,
  bio() { return `I'm ${this.name}`; }
};

// Destructuring (modern)
const { name, age } = user;
const [first, ...rest] = skills;

// === Conditionals ===
if (count > 10) {
  console.log('Big count!');
} else if (count > 5) {
  console.log('Mid count');
} else {
  console.log('Small count');
}

// Ternary (inline if/else)
const label = count > 10 ? 'Big' : 'Small';

// === Loops ===
skills.forEach(skill => console.log(skill));

for (const skill of skills) {
  console.log(skill);
}

🌳 DOM Manipulation

The DOM (Document Object Model) is JavaScript's representation of your HTML. You can read, change, add, and remove elements using JS.

JavaScript — DOM
// === Select Elements ===
const title   = document.querySelector('h1');
const btn     = document.querySelector('#submit-btn');
const cards   = document.querySelectorAll('.card');
const nav     = document.getElementById('nav');

// === Read & Modify Content ===
title.textContent = 'New Title';       // text only (safe)
title.innerHTML   = 'Title <span>!</span>'; // HTML (careful!)

// === Modify Styles ===
btn.style.backgroundColor = '#0038FF';
btn.style.display = 'none'; // hide

// === CSS Classes (preferred over inline styles) ===
btn.classList.add('active');
btn.classList.remove('hidden');
btn.classList.toggle('open');    // add if absent, remove if present
btn.classList.contains('active'); // returns true/false

// === Attributes ===
btn.setAttribute('disabled', '');
btn.getAttribute('href');
btn.removeAttribute('disabled');

// === Create & Insert Elements ===
const newCard = document.createElement('div');
newCard.className = 'card';
newCard.textContent = 'New card!';
document.body.appendChild(newCard);

// === Events ===
btn.addEventListener('click', (e) => {
  e.preventDefault(); // stop default action
  console.log('Button clicked!');
});

// Common events: click, submit, keydown, mouseover, scroll, resize, load
window.addEventListener('scroll', () => {
  const scrolled = window.scrollY;
  nav.style.background = scrolled > 100
    ? 'rgba(0,0,0,0.95)'
    : 'transparent';
});

Fetch API & Async/Await

The Fetch API lets you get data from external services (weather, news, user data) without refreshing the page.

JavaScript — Async Data Fetching
// === Basic Fetch (async/await — the modern way) ===
async function getWeather(city) {
  try {
    // fetch() returns a Promise
    const response = await fetch(
      `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_KEY`
    );

    // Check for HTTP errors
    if (!response.ok) {
      throw new Error(`HTTP error: ${response.status}`);
    }

    // Parse JSON response
    const data = await response.json();
    console.log(data); // use your data!
    return data;

  } catch (error) {
    console.error('Fetch failed:', error);
  }
}

// Call it:
getWeather('London');

// === POST request (send data) ===
async function submitForm(formData) {
  const res = await fetch('/api/contact', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(formData),
  });
  return res.json();
}

// === Parallel fetches (faster!) ===
const [users, posts] = await Promise.all([
  fetch('/api/users').then(r => r.json()),
  fetch('/api/posts').then(r => r.json()),
]);

Three.js — 3D in the Browser

Three.js is a JavaScript library that makes WebGL 3D graphics approachable. You can create stunning 3D scenes like the one on this page's hero section.

HTML + JavaScript — Three.js Setup
<!-- 1. Add canvas to HTML -->
<canvas id="three-canvas"></canvas>

<!-- 2. Load Three.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>

<script>
// 3. Create scene, camera, renderer
const scene    = new THREE.Scene();
const camera   = new THREE.PerspectiveCamera(75, innerWidth/innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({
  canvas: document.getElementById('three-canvas'),
  alpha: true,     // transparent background
  antialias: true  // smooth edges
});

renderer.setSize(innerWidth, innerHeight);
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
camera.position.z = 5;

// 4. Add lighting
scene.add(new THREE.AmbientLight(0xffffff, 0.5));
const light = new THREE.PointLight(0xf97316, 2, 100);
light.position.set(5, 5, 5);
scene.add(light);

// 5. Create a 3D object
const geometry = new THREE.IcosahedronGeometry(1.5, 1);
const material = new THREE.MeshPhongMaterial({
  color: 0xf97316,
  wireframe: true
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

// 6. Animation loop
function animate() {
  requestAnimationFrame(animate);
  mesh.rotation.x += 0.005;
  mesh.rotation.y += 0.01;
  renderer.render(scene, camera);
}
animate();
</script>

⚛️ React Introduction

React is the most popular JS framework. It lets you build UIs with reusable components and automatically updates the page when data changes.

Do you need React?
Not for simple sites! Use React when you have complex state (logged-in users, shopping carts, live data). For landing pages and portfolios, plain HTML/CSS/JS is faster and simpler. Don't over-engineer!
JSX — React Component
// A React component is just a function that returns JSX

import { useState, useEffect } from 'react';

// Reusable Card component
function StageCard({ title, desc, emoji, link }) {
  return (
    <a href={link} className="glass-card">
      <div className="card-icon">{emoji}</div>
      <h3>{title}</h3>
      <p>{desc}</p>
    </a>
  );
}

// Component with state
function Counter() {
  const [count, setCount] = useState(0); // state hook

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

// Side effects (fetch data on mount)
function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch(`/api/users/${userId}`)
      .then(r => r.json())
      .then(setUser);
  }, [userId]); // re-run when userId changes

  if (!user) return <p>Loading...</p>;
  return <h2>{user.name}</h2>;
}

Stage 2 Project: Animated Portfolio

Upgrade your Stage 1 site with:

Glassmorphism nav bar that changes on scroll
CSS Grid portfolio section with hover effects
Smooth CSS animations on page load (fadeInUp)
Dark mode using CSS variables + prefers-color-scheme
A Three.js background animation
Fully responsive at all screen sizes
Pro Tip: Use CSS Custom Properties for theming
Define all your colors as CSS variables. Then toggling dark mode is just changing 3-4 variable values. This is how real production sites handle theming — no JS needed.
PreviousStage 1 — Basics