An honest, no-holds-barred guide for developers new to both technologies.
Based on the code in JJ's Sketch & Draw App — a real project, real trade-offs.
Start here if you are new to either — or both.
The native language of web styling — built into every browser.
CSS (Cascading Style Sheets) is the language browsers use to decide how HTML elements look — their colours, sizes, spacing, animations, and layout. Every website on the internet uses CSS. When we say "vanilla CSS" we mean writing those rules yourself, from scratch, without any helper library.
You write rules in a .css file. Each rule targets an element and
declares how it should look:
/* target .btn, set its colour */
.btn {
background: #667eea;
color: white;
padding: 10px 20px;
border-radius: 8px;
}
Analogy: Think of vanilla CSS as cooking from scratch with raw ingredients. You control every flavour — but you have to prepare everything yourself.
The world's most popular CSS framework — used on millions of sites.
Bootstrap 5 is a free, open-source framework — a large pre-written CSS (and JavaScript) library that gives you hundreds of ready-made components and layout tools. Instead of writing every rule from scratch, you add Bootstrap's classes to your HTML and the styling is applied automatically.
You link Bootstrap's stylesheet in <head>, then use its
built-in class names in your HTML:
<!-- Bootstrap handles all the CSS -->
<button class="btn btn-primary">
Click me
</button>
Analogy: Bootstrap is like a meal-kit service. The ingredients are pre-measured and the instructions are included — you assemble, you don't invent.
jjSketchDrawBootstrap5Styles.css file does.
Real examples from JJ's Sketch & Draw App — same visual result, different techniques.
/* CSS — ~30 lines to build the modal */
.modal { display: none; position: fixed;
z-index: 1000; width: 100%; height: 100%;
background: rgba(0,0,0,0.5);
backdrop-filter: blur(4px); }
.modal.show { display: flex;
align-items: center;
justify-content: center; }
/* ... animation, content, header etc. */
// JavaScript — 3 separate event listeners
settingsBtn.addEventListener('click', () => {
settingsModal.classList.add('show');
});
closeBtn.addEventListener('click', () => {
settingsModal.classList.remove('show');
});
window.addEventListener('click', (e) => {
if (e.target == settingsModal)
settingsModal.classList.remove('show');
});
<!-- HTML only — zero JavaScript required -->
<button
data-bs-toggle="modal"
data-bs-target="#resourcesModal">
📚 Resources
</button>
<div class="modal fade" id="resourcesModal">
<div class="modal-dialog modal-xl
modal-dialog-centered">
<div class="modal-content">
<button data-bs-dismiss="modal">✕</button>
</div>
</div>
</div>
// JavaScript needed: NONE ✓
/* Requires writing the grid from scratch */
.drawings-grid {
display: grid;
grid-template-columns:
repeat(auto-fill, minmax(220px, 1fr));
gap: 25px;
}
.drawing-card {
background: white;
border-radius: 12px;
box-shadow: 0 5px 15px rgba(0,0,0,0.08);
transition: transform 0.3s;
border: 1px solid #f0f0f0;
}
.drawing-card:hover {
transform: translateY(-8px);
box-shadow: 0 15px 35px rgba(102,126,234,0.2);
}
<!-- Responsive at 1/2/3/4 cols automatically -->
<div class="row
row-cols-1
row-cols-sm-2
row-cols-md-3
row-cols-lg-4
g-4">
<div class="col">
<div class="card h-100 shadow-sm">
<!-- card content -->
</div>
</div>
</div>
/* CSS needed: NONE for responsive grid ✓ */
style.css is ~690 lines.
The Bootstrap version's jjSketchDrawBootstrap5Styles.css is ~130 lines.
Both pages look nearly identical. That is a ~81% reduction in CSS code.
No marketing spin. What each approach actually costs and delivers.
class="d-flex align-items-center gap-3 justify-content-between"Category by category — who wins?
| Category | Vanilla CSS | Bootstrap 5 | Winner |
|---|---|---|---|
| Development speed | Every rule hand-written. A professional-quality UI from scratch takes days to weeks. | Pre-built components and utility classes. The same UI takes hours. | Bootstrap |
| Code volume | ~690 lines of CSS for the drawing app. | ~130 lines of custom CSS (Bootstrap handles the rest). | Bootstrap |
| Responsive design | You must write every media query manually for every breakpoint. | Built-in 12-col grid + breakpoint utility classes handle it automatically. | Bootstrap |
| Accessibility | You must add ARIA roles, keyboard support, and focus traps yourself — easy to miss. | Bootstrap components ship with correct ARIA, keyboard navigation, and focus management by default. | Bootstrap |
| Design uniqueness | Unlimited — your design is entirely your own. | Can look "Bootstrap-ish" without deliberate customisation (custom colours, fonts, etc.). | Vanilla CSS |
| Learning value | Teaches you exactly what is happening under the hood. Foundational knowledge transfers everywhere. | Great for productivity, but can leave gaps in understanding if used exclusively. | Vanilla CSS |
| Page load size | Ships exactly what you write — nothing more. | ~230KB CSS + ~78KB JS bundle loaded from CDN (cached across sites). Acceptable for most projects. | Tie* |
| JavaScript needed | You must write your own modal, dropdown, and tab logic (script.js adds ~60 extra lines for this). | Components like modals and tabs work via HTML data attributes — zero extra JavaScript. | Bootstrap |
| Cross-browser support | You must test and fix quirks yourself. | Bootstrap team has already dealt with browser inconsistencies across every major browser. | Bootstrap |
| Maintainability | Grows to be very large in real projects. Style drift between pages is common. | Utility-first classes enforce consistency. Any developer familiar with Bootstrap can read the code. | Bootstrap |
| Brand customisation | Straightforward — every value is yours to set. | Possible via CSS variables or Sass, but requires extra configuration steps. | Tie |
| Score | CSS wins: 2 categories | Bootstrap wins: 7 categories | Ties: 2 |
* The load-size tie: Bootstrap's CDN files are cached by browsers after the first visit (used across millions of sites), so the practical cost after the first page load is often zero. For very small single-page projects, vanilla CSS is genuinely lighter. For multi-page apps, CDN caching makes Bootstrap effectively free.
No hedging. Here is what the data actually says.
Write vanilla CSS first. Build a few projects without any framework. Struggle with flexbox, fight specificity, make it responsive manually. This pain is the education. Once you understand why CSS works the way it does, Bootstrap becomes dramatically more powerful in your hands.
For real projects — apps, class assignments, portfolios — Bootstrap lets you spend your time on the unique parts of your project rather than re-inventing standard UI patterns. Add a small custom CSS file (like this app does) for your brand colours and any component Bootstrap can't provide.
Senior developers reach for Bootstrap for speed on standard UI, but write vanilla CSS for custom animations, brand-specific components, and fine-tuned performance optimisation. The combination is what makes production-quality web apps possible on real-world timelines.
How to build new pages with the same look and feel as the drawing app — efficiently.
Copy the two CDN tags (CSS in <head>, JS bundle before </body>)
into your HTML template. This gives you the entire framework's layout, components, and utilities
instantly — no installation, no build step.
Put your gradient colours (#667eea → #764ba2), the app-container card style,
the glass button, and the sticky footer into a single file (e.g.,
tntBrandStyles.css). Link it after Bootstrap on every page. This is how
professional design systems work — Bootstrap handles the scaffold, you apply the brand.
Define :root { --brand-start: #667eea; --brand-end: #764ba2; } once and use
var(--brand-start) everywhere. When the colour scheme changes, update one line
instead of hunting through hundreds of rules.
If your custom CSS file grows beyond ~200 lines, ask yourself: "Is Bootstrap already doing
this?" Look for Bootstrap utility classes (shadow-sm, rounded,
text-muted, fw-bold) before writing new rules. The ideal ratio
is roughly 80% Bootstrap utilities, 20% custom CSS.
Use the W3C Validator.
The two most common Bootstrap-related errors to watch for:
(a) role="tablist" without aria-label or aria-labelledby, and
(b) heading levels that skip a number (h1 → h3, skipping h2).
Both of these appeared in the drawing app and were corrected.
pageName.html (Bootstrap markup + data attributes) +
pageNameStyles.css (brand overrides only, ~100–150 lines) +
pageNameScript.js (application logic, no UI boilerplate).
This separation is clean, predictable, and scales well as your project grows.
Once you are comfortable with Bootstrap 5, explore Tailwind CSS — a utility-first framework that is even more flexible than Bootstrap and is now the dominant choice in professional front-end development. The concepts you learn with Bootstrap (utility classes, responsive prefixes, component thinking) transfer directly.
The utility classes used most often in the drawing app.
Pattern: p/m + side (t/b/s/e/x/y) + size (0–5).
e.g. pt-3 = padding-top: 1rem
These replace JavaScript event listeners for standard UI interactions. Bootstrap's JS bundle reads them automatically.