Logo Gerardo Perrucci - Full Stack Developer

Modern Front-End Development: From HTML and CSS to Angular, React, and Vue

Modern Front-End Development

Decorative quote icon

Any application that can be written in JavaScript, will eventually be written in JavaScript.

— Jeff Atwood
Decorative quote icon

JavaScript is the duct tape of the Internet.

— Charlie Campbell

When you browse an online store, filter products, compare prices, and complete a checkout flow, you are living inside the front end of a web application. That experience is powered by a layered stack of technologies: HTML for structure, CSS for design, JavaScript for interactivity, and increasingly preprocessors and frameworks to keep growing codebases maintainable.

Table of Contents

  1. The Foundation: HTML, CSS, and JavaScript Working Together
  2. Scaling Your Styles: From CSS to Sass and Less
  3. Adaptive vs Responsive Design
  4. JavaScript Frameworks: Angular, React, and Vue
  5. The Evolving Role of the Front-End Developer
  6. A Pragmatic Learning Path
  7. Further Reading and Official Resources
  8. References

The Foundation: HTML, CSS, and JavaScript Working Together

The classic front-end stack is deliberately simple:

  • HTML (HyperText Markup Language) defines the structure of the page: headings, paragraphs, links, forms, images, and so on. It is the "skeleton" the browser renders.
  • CSS (Cascading Style Sheets) defines the presentation: layout, colors, spacing, typography, and responsive behavior across devices.
  • JavaScript adds behavior and interactivity: handling clicks, loading data dynamically, and updating the UI without full page reloads.

The source text already outlines this division: HTML provides the physical structure, CSS gives it a consistent and appealing look, and JavaScript turns static pages into intuitive and interactive experiences.

A classic example is a login button:

<!-- index.html -->
<button id="login-button">Log in</button>
<script type="module" src="main.js"></script>
// main.ts – TypeScript compiled to JavaScript
const loginButton = document.querySelector<HTMLButtonElement>('#login-button');

if (!loginButton) {
  throw new Error('Login button not found');
}

loginButton.addEventListener('click', () => {
  // In a real app, you would call your API instead of using alert()
  alert('Logging in...');
});

Here:

  • HTML defines what exists (<button>),
  • CSS (not shown) defines how it looks,
  • TypeScript/JavaScript defines what it does when clicked.

Over time JavaScript has become so central to the web that Jeff Atwood famously observed: "Any application that can be written in JavaScript, will eventually be written in JavaScript." Charlie Campbell described it even more bluntly: "JavaScript is the duct tape of the Internet."

Those quotes are not just jokes; they reflect the reality that front-end developers now build full applications in the browser, not just decorative scripts.

Scaling Your Styles: From CSS to Sass and Less

Plain CSS is perfectly adequate for small sites. But as soon as you are styling a complex e-commerce application with hundreds of components, maintainability becomes the main problem:

  • Repeated colors and spacing values everywhere
  • Deeply nested selectors that are hard to refactor
  • Difficulty sharing style logic across pages and components

This is where Sass and Less come in, both highlighted in your original material.

Sass (Syntactically Awesome Style Sheets)

Sass is a stylesheet language compiled to CSS. It adds variables, nesting, mixins, and functions while remaining fully CSS-compatible.

Sass example (SCSS syntax):

// styles.scss
$primary-color: #0f766e;
$spacing-md: 1rem;

.button {
  background-color: $primary-color;
  padding: $spacing-md $spacing-md * 2;
  border-radius: 0.375rem;
  color: white;
  font-weight: 600;

  &:hover {
    background-color: darken($primary-color, 8%);
  }
}

Compiled CSS:

.button {
  background-color: #0f766e;
  padding: 1rem 2rem;
  border-radius: 0.375rem;
  color: white;
  font-weight: 600;
}

.button:hover {
  background-color: #0d635d;
}

When Sass is a good fit

  • Large design systems where you need consistent tokens (colors, spacing, typography).
  • Teams that benefit from mixins and functions to encapsulate tricky CSS patterns.
  • Projects that already have a build step (Webpack, Vite, etc.), because Sass needs compilation.

Less (Leaner Style Sheets)

Less is another CSS extension language, originally inspired by Sass, which adds variables, mixins, operations, and functions while staying close to plain CSS syntax. It compiles to CSS via less.js in the browser or Node.js on the server.

Less example:

// styles.less
@primary-color: #2563eb;
@spacing-md: 1rem;

.button {
  background-color: @primary-color;
  padding: @spacing-md (@spacing-md * 2);
  border-radius: 6px;
  color: white;
  font-weight: 600;

  &:hover {
    background-color: darken(@primary-color, 10%);
  }
}

When Less is a good fit

  • Existing ecosystems that already use Less (some CMSs, older design systems, legacy projects).
  • Teams that prefer minimal deviation from plain CSS syntax.
  • Environments where compiling in the browser with less.js is convenient.

Sass vs Less vs Plain CSS (in Practice)

  • If you are building a modern greenfield project, Sass tends to be the safer long-term bet due to its ecosystem, tooling, and active spec.
  • If you are working inside a legacy project that already uses Less, stick with it; the cost of migration is often higher than the benefits.
  • For small sites or simple pages, well-structured plain CSS (potentially with CSS custom properties) keeps the toolchain simpler and is often enough.

From an architectural perspective: preprocessors are not mandatory, but they are often the difference between a stylesheet you can safely evolve and one you are afraid to touch.

Adaptive vs Responsive Design

Your source text calls out two important concepts: adaptive and responsive websites.

  • In an adaptive design, you design distinct layouts for specific screen sizes (for example, 320px mobile, 768px tablet, 1024px desktop). The server or client chooses the most appropriate layout. You might deliberately show less detail on mobile than on desktop.
  • In a responsive design, the same layout scales fluidly with the viewport. Content reorganizes and resizes using flexible grids, percentages, and modern CSS functions like min(), max(), and clamp().

A simple responsive card layout illustrates the idea:

/* Mobile first */
.product-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

/* Two columns on medium screens, three on large */
@media (min-width: 640px) {
  .product-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .product-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

Which approach should you favor?

  • Use responsive design by default. It works well for most content and is easier to maintain because you have a single fluid layout.
  • Use adaptive design when you intentionally want different experiences or content per device class (for example, a mobile-only checkout flow, or radically different navigation).

Both approaches rely heavily on CSS; frameworks do not remove the need for careful layout and typography.

JavaScript Frameworks: Angular, React, and Vue

As front-end applications grow, manipulating the DOM by hand with vanilla JavaScript quickly becomes error-prone. You need components, routing, state management, and a way to keep UI and data in sync. This is why the original text introduces JavaScript frameworks such as Angular, React, and Vue.

All three are built on top of HTML, CSS, and JavaScript/TypeScript, but they make different trade-offs.

Angular: Batteries Included

What it is. Angular is a TypeScript-first web framework for building large-scale, single-page and multi-page applications. It ships with routing, forms, HTTP utilities, and opinionated architecture out of the box.

Minimal Angular component (TypeScript):

// product-card.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-product-card',
  template: `
    <article class="product-card">
      <h3>{{ name }}</h3>
      <p>{{ price | currency }}</p>
      <button type="button" (click)="addToCart.emit()">Add to cart</button>
    </article>
  `,
})
export class ProductCardComponent {
  @Input() name = '';
  @Input() price = 0;
  @Output() addToCart = new EventEmitter<void>();
}

Strengths

  • Strong conventions and structure; easier to scale large teams and codebases.
  • Integrated solutions for routing, forms, and dependency injection.
  • Backed by Google with an extensive CLI and documentation.

Weaknesses

  • Steeper learning curve, especially for small or design-heavy front-ends.
  • More boilerplate than lightweight libraries like React or Vue.

Typical use cases

  • Enterprise dashboards, internal tools, and large admin portals.
  • Projects where consistency and long-term maintainability matter more than raw speed of prototyping.

Official resources: Angular docs, angular/angular on GitHub.

React: The UI Library

What it is. React describes itself as "the library for web and native user interfaces" and focuses on building UIs as reusable components. It does not dictate routing, data fetching, or state management; those concerns are usually handled by companion libraries.

Minimal React + TypeScript component:

// ProductCard.tsx
import React from 'react';

type ProductCardProps = {
  name: string;
  price: number;
  onAddToCart: () => void;
};

export const ProductCard: React.FC<ProductCardProps> = ({
  name,
  price,
  onAddToCart,
}) => {
  return (
    <article className="product-card">
      <h3>{name}</h3>
      <p>${price.toFixed(2)}</p>
      <button type="button" onClick={onAddToCart}>
        Add to cart
      </button>
    </article>
  );
};

You can drop this component into any React application (Next.js, Remix, Vite, etc.) and reuse it across pages.

Strengths

  • Very flexible: you compose your own stack from best-of-breed libraries (React Router, TanStack Query, etc.).
  • Huge ecosystem and community, widely used in industry.
  • Works across web and native (React Native).

Weaknesses

  • Freedom comes at a price: you must make more architectural decisions.
  • The ecosystem moves fast; keeping up requires deliberate effort.

Typical use cases

  • Product teams that need to move quickly and iterate on UX.
  • Startups and large consumer apps (dashboards, e-commerce, media apps).
  • When you expect to reuse logic between web and mobile.

Official resources: React docs, facebook/react on GitHub.

Vue: Approachable and Progressive

What it is. Vue is a progressive JavaScript framework for building user interfaces. It builds on top of standard HTML, CSS, and JavaScript, and can be introduced gradually into existing pages or used to power full single-page apps.

Minimal Vue 3 component with TypeScript (<script setup>):

<!-- ProductCard.vue -->
<script setup lang="ts">
const props = defineProps<{
  name: string;
  price: number;
}>();

const emit = defineEmits<{
  (e: 'add-to-cart'): void;
}>();

function handleClick() {
  emit('add-to-cart');
}
</script>

<template>
  <article class="product-card">
    <h3>{{ props.name }}</h3>
    <p>{{ props.price.toFixed(2) }}</p>
    <button type="button" @click="handleClick">
      Add to cart
    </button>
  </article>
</template>

Strengths

  • Very approachable: templates feel close to plain HTML.
  • Can act as a small library embedded into a server-rendered app or as a full framework with official router and state management (Vue Router, Pinia).
  • Excellent documentation and tooling (Vite + Vue).

Weaknesses

  • Smaller ecosystem than React in some specialized niches.
  • Some organizations are still more familiar with React/Angular, which can influence hiring.

Typical use cases

  • Teams that want simplicity and clarity in templates.
  • Progressive enhancement of existing server-rendered sites.
  • Projects where design and UX experimentation matter but you still want structure.

Official resources: Vue docs, vuejs/core on GitHub.

Choosing Between Angular, React, and Vue

You rarely choose purely on "popularity"; you choose based on constraints and context:

  • If you want strong conventions, integrated tooling, and a single way of doing things, Angular is compelling.
  • If you want maximum flexibility and ecosystem depth, React is often the pragmatic choice.
  • If you want a gentle learning curve and progressive adoption, Vue is an elegant middle ground.

What matters most is consistency: once you pick a framework, design shared patterns (folder structure, state management approach, testing strategy) so that your front-end can evolve without collapsing under its own complexity.

The Evolving Role of the Front-End Developer

The original text closes by pointing out that front-end developers must ensure sites work across multiple browsers, operating systems, and devices and continuously update their work as technologies evolve.

Today that role is even broader:

  • You are responsible for accessibility, ensuring keyboard and screen-reader users can complete the same flows.
  • You care about performance, because slow websites directly impact conversion and user retention.
  • You navigate a fast-moving ecosystem of tools and frameworks, but still rely on the stable foundations of HTML, CSS, and JavaScript.

A practical way to keep up without drowning in trends is to double down on web fundamentals. MDN's Learn Web Development remains one of the best vendor-neutral resources for this.

A Pragmatic Learning Path

If you are building or mentoring a learning journey, a sensible order is:

  1. Master HTML and CSS. Understand semantic markup, flexbox, grid, and responsive layouts without frameworks.
  2. Get comfortable with JavaScript/TypeScript in the browser. Manipulate the DOM, handle events, and call APIs using fetch.
  3. Introduce Sass or Less when CSS starts to hurt. Use variables and mixins to encode your design system instead of copy-pasting values.
  4. Pick one framework (Angular, React, or Vue) and go deep. Build at least one end-to-end app: routing, forms, API integration, authentication, and error handling.
  5. Refine with real products. Profiles, carts, dashboards, and internal tools are far better teachers than contrived to-do lists.

The goal is not to know every tool, but to understand how structure (HTML), style (CSS/Sass/Less), and behavior (JavaScript/TypeScript + frameworks) fit together into maintainable systems.

Further Reading and Official Resources

Core Web Technologies

Preprocessors

Frameworks

References

Original Source