Home › Practice Tools › Notepad / Code Sandbox
๐Ÿ“
Coding

Notepad / Code Sandbox

Practice coding right here in the browser - write, run and preview HTML, CSS and JavaScript instantly. Save and share your projects.
Ideal for: Beginner web-development students who want an instant HTML/CSS/JS playground with zero setup.

What you'll practice

Start practicing

Notepad / Code Sandbox is part of Practice Tools. Sign in or create an account, then subscribe for โ‚ฆ4,000/month to unlock it.

๐Ÿ“‹ Lab Instructions

Step-by-step exercises for Notepad / Code Sandbox - read them here, then practice live in the tool above.

Lab Instructions Beginner

Last updated: August 9, 2026
Getting Started with the Code Sandbox (Notepad)
Beginner · Coding

๐Ÿ“ Getting Started with the Code Sandbox

Notepad / Code Sandbox โ€” Lab 1
What you're practicing: writing your first lines of HTML, CSS and JavaScript, and instantly seeing them turn into a real webpage โ€” right in your browser, with nothing to install and nothing that can "break" your computer. Every step below shows the exact code to type and what you should see happen.
  1. Click "Open" to launch the sandbox

    This gives you three writing areas โ€” HTML, CSS, and JavaScript โ€” plus a live preview panel where your page appears as you type.

    You should see: three empty code boxes and a blank white preview panel.
  2. Type this into the HTML box

    HTML is the structure of a page. Type exactly this:

    <h1>Hello, I'm coding!</h1>
    <p>This is my first webpage.</p>
    You should see: nothing yet โ€” the preview only updates once you click Run.
  3. Click Run / Preview

    Your plain text becomes a real webpage. This "write โ†’ run โ†’ look" loop is the single most important habit to build.

    You should see: a bold heading "Hello, I'm coding!" and a line of text below it, in plain black text on white.
  4. Add this to the CSS box, then Run again

    CSS controls appearance. Type:

    h1 {
      color: darkgreen;
      font-family: Arial;
    }
    body {
      background: #f4f4f4;
    }
    You should see: the heading turn dark green, and the page background turn light grey.
  5. Change ONE value and re-run

    Edit darkgreen to darkred (or any CSS color name) and click Run again.

    You should see: only the heading color changes โ€” nothing else moves. That's confirmation you understand exactly which line controls what.
  6. Add a button in HTML

    Below your paragraph in the HTML box, add:

    <button id="myBtn">Click me</button>
    You should see: a plain grey button appear under your text after you click Run.
  7. Make it interactive with JavaScript

    In the JS box, type:

    document.getElementById("myBtn").onclick = function() {
      document.querySelector("h1").textContent = "You clicked it!";
    };
    You should see: the heading text change to "You clicked it!" every time you click the button. If nothing happens, check that your button's id matches exactly (myBtn) in both boxes.
  8. Break it on purpose

    Delete the closing } from your JavaScript and click Run.

    You should see: an error, or the button silently stops working. Put the } back and confirm it works again. This is what debugging feels like โ€” it's normal, even for professionals.
  9. Save your work

    Click Save to keep this under My Projects, so you can reopen or share it later.

    You should see: a confirmation that your project was saved, and it should now appear in your project list.
  10. Explain what you built, in one sentence

    Say it out loud or write it down: "I built a page with a heading, styled text, and a button that changes the heading when clicked." If you can say that without looking at your code, you actually understood it.

Tip Build in the smallest possible steps and preview constantly. When something breaks, it's far easier to find the problem if you only changed one thing since the last time it worked. This "change one thing, check the result" loop is exactly what professional developers do every day, just faster.

๐Ÿงช Try it right now

This mini sandbox is pre-loaded with the finished example from the steps above. Edit anything and click Run to see it change live.
Edit the code above, then click Run to update the preview below.
CRMNuggets · Practice Tools · Code Sandbox Guide

Website Design Lab Intermediate

Last updated: August 9, 2026
Lab 2: An Interactive Component (Intermediate) โ€” Code Sandbox
Intermediate · Coding

๐Ÿ” Lab 2: An Interactive Component

Notepad / Code Sandbox โ€” builds on Lab 1
What you're practicing: in Lab 1 you built a styled button and a simple click handler. Now you'll build something with actual changing state โ€” a value that updates over time, and an interface that has to stay in sync with it. Each step below shows the exact code and what you should see happen.
  1. Set up the structure

    In your HTML box, add a large number display and two buttons โ€” one to increase, one to decrease:

    <h1 id="count">0</h1>
    <button id="increase">+</button>
    <button id="decrease">โˆ’</button>
    You should see: a "0" heading with two plain buttons underneath after you click Run.
  2. Create a variable to hold the state

    In JavaScript, store the real number in a variable and update the display from that variable โ€” never change the text directly without updating the variable too.

    let count = 0;
    document.getElementById("increase").onclick = function() {
      count = count + 1;
      document.getElementById("count").textContent = count;
    };
    This one variable (count) is the "source of truth." The number on screen is just a reflection of it โ€” that idea is the core of this whole lab.
  3. Wire up the decrease button

    Add the matching handler, subtracting instead of adding:

    document.getElementById("decrease").onclick = function() {
      count = count - 1;
      document.getElementById("count").textContent = count;
    };
    You should see: the number go up when you click +, and down when you click โˆ’. Click both a few times to confirm.
  4. Make the current state obvious

    In CSS, make the number large, bold, and centered โ€” a user should read it at a glance:

    #count {
      font-size: 48px;
      text-align: center;
    }
    button {
      padding: 8px 16px;
      font-size: 18px;
    }
  5. Add the edge case: no negative numbers

    This is the real intermediate skill โ€” handling what happens at the boundary, not just the normal path. Guard the decrease so it can't go below zero:

    document.getElementById("decrease").onclick = function() {
      if (count > 0) {
        count = count - 1;
        document.getElementById("count").textContent = count;
      }
    };
    You should see: the count stop exactly at 0 no matter how many more times you click โˆ’. Before this change, try to actually see it go negative โ€” then add the fix and confirm it can't anymore.
  6. Add a reset button

    In HTML add a third button, and in JavaScript wire it up to restore the starting value:

    <button id="reset">Reset</button>
    
    document.getElementById("reset").onclick = function() {
      count = 0;
      document.getElementById("count").textContent = count;
    };
  7. Deliberately try to break it

    Click increase and decrease rapidly and out of order. Click reset mid-run. Click decrease many times right after loading the page. Ask yourself: does the number on screen ever disagree with what the real count should be?

    You should see: the display stay accurate every time โ€” if it doesn't, that's a real bug to track down, not something to ignore.
  8. Notice the pattern

    Every single time you changed count, you also had to remember to update the text on screen in the same place. In a small project that's manageable by hand โ€” forgetting that second line is one of the most common real-world bugs, and it's exactly the problem that more advanced frameworks are built to solve later on.

  9. Save your project

    Once it behaves correctly at zero, at large numbers, and after reset, click Save to keep it under My Projects.

Tip "What happens at the edges" (zero, empty, maximum) is where most real bugs live. Get in the habit of deliberately testing edge cases โ€” not just the normal, happy-path click โ€” every time you build something interactive. A counter that's only ever tested by clicking "increase" a few times will hide its bugs until a real user finds them for you.

๐Ÿงช Try it right now

Pre-loaded with the finished counter from the steps above, including the zero-guard and reset button. Edit anything and click Run.
Try removing the "if (count > 0)" check and see the counter go negative โ€” then put it back.
CRMNuggets · Practice Tools · Code Sandbox โ€” Lab 2 (Intermediate)

Expert Level Lab Ezzercise

Last updated: August 9, 2026
Lab 3: A Small Multi-Feature App (Expert) โ€” Code Sandbox
Expert · Coding

โœ… Lab 3: A Small Multi-Feature App

Notepad / Code Sandbox โ€” builds on Labs 1 & 2
What you're practicing: in Labs 1โ€“2 you built a styled interactive element with state and an edge case. Now you'll combine several pieces of interactive logic into one small, cohesive project โ€” a to-do list with adding, completing, deleting, and a live remaining-count, all staying in sync with each other.
  1. Pick the idea and set up the structure

    We'll build a to-do list: add an item, mark it done, delete it, and show a live count remaining. Don't build the whole thing yet โ€” start with just the structure:

    <input id="taskInput" placeholder="New task">
    <button id="addBtn">Add</button>
    <ul id="taskList"></ul>
    <p id="remaining">0 remaining</p>
  2. Build feature one: adding an item

    Store tasks in an array โ€” your single source of truth, exactly like the count variable in Lab 2, just holding a list instead of a number:

    let tasks = [];
    
    document.getElementById("addBtn").onclick = function() {
      let text = document.getElementById("taskInput").value;
      if (text.trim() === "") return;
      tasks.push({ text: text, done: false });
      document.getElementById("taskInput").value = "";
      render();
    };
    
    function render() {
      let list = document.getElementById("taskList");
      list.innerHTML = "";
      tasks.forEach(function(task, index) {
        let li = document.createElement("li");
        li.textContent = task.text;
        list.appendChild(li);
      });
    }
    Stop here. Run it, type a task, click Add, confirm it appears in the list. Get this ONE feature fully working before writing anything else โ€” that's the entire point of this lab.
  3. Build feature two: marking an item done

    Inside the forEach, add a checkbox that updates the array (not just the screen) when clicked:

    let checkbox = document.createElement("input");
    checkbox.type = "checkbox";
    checkbox.checked = task.done;
    checkbox.onclick = function() {
      tasks[index].done = !tasks[index].done;
      render();
    };
    li.prepend(checkbox);
    if (task.done) {
      li.style.textDecoration = "line-through";
    }
    You should see: checking a box strikes the task through; unchecking removes the strikethrough.
  4. Build feature three: deleting an item

    Add a delete button per item that removes it from the array itself:

    let deleteBtn = document.createElement("button");
    deleteBtn.textContent = "โœ•";
    deleteBtn.onclick = function() {
      tasks.splice(index, 1);
      render();
    };
    li.appendChild(deleteBtn);
    You should see: deleting a task from the middle of the list removes exactly that one โ€” not the last item on screen by accident.
  5. Connect the features: a live remaining count

    This is what separates a pile of features from a real app โ€” parts that stay in sync. Update it inside render(), since that's your one place the display refreshes:

    let remainingCount = tasks.filter(function(t) { return !t.done; }).length;
    document.getElementById("remaining").textContent = remainingCount + " remaining";
    You should see: the count go down when you check a task, back up when you uncheck it, and down when you delete an unfinished one. If any of those disagree, that's the bug to chase before moving on.
  6. Add basic styling

    Space out list items, dim completed tasks, and style the input/buttons so the app feels intentional rather than like a bare test page.

  7. Deliberately try to break your own app

    Click Add with an empty input. Add the same task twice. Delete every task and check what "remaining" shows at zero. Check and uncheck rapidly. Fix anything that misbehaves.

  8. Save your finished project

    Once every feature works correctly on its own and together, click Save to keep it under My Projects.

Tip Build features in the smallest possible slices, and preview constantly. Trying to write an entire multi-feature app in one go before testing anything is the single biggest reason beginners get stuck debugging โ€” by the time something breaks, there are ten new lines to suspect instead of one. Get feature one fully working, confirm it, then move to feature two.

๐Ÿงช Try it right now

Pre-loaded with the finished to-do list from the steps above. Edit anything and click Run.
Add a few tasks, check some off, delete one, and watch "remaining" stay accurate.
CRMNuggets · Practice Tools · Code Sandbox โ€” Lab 3 (Expert)