Tutoriales gratuitos

Aprende
Desarrollo Web.

Tutoriales completos y bien estructurados de HTML5, CSS3, JavaScript y React. Desde cero hasta nivel profesional.

4 Tecnologías
30+ Secciones
100% Gratis

Tecnologías
del stack web

Explora cada tecnología con tutoriales paso a paso, ejemplos prácticos y código listo para usar.

📄

01 — Fundamentos

HTML5

Estructura semántica, formularios avanzados, Canvas, Audio y Video para la web moderna.

Semántica Formularios Canvas Multimedia
🎨

02 — Diseño

CSS3

Flexbox, Grid, animaciones fluidas y diseño responsive para cualquier dispositivo.

Flexbox Grid Animaciones Responsive

03 — Programación

JavaScript

ES6+, manipulación del DOM, Async/Await y consumo de APIs REST modernas.

ES6+ DOM Async/Await APIs
⚛️

04 — Frameworks

React

Componentes, Hooks, gestión de estado y efectos para interfaces reactivas y modernas.

Componentes Hooks Estado Props

Aprende de manera
clara y directa.

Contenido diseñado para desarrolladores que valoran su tiempo. Sin relleno, sin distracciones — solo lo que necesitas para construir cosas reales.

01

Contenido Completo

Tutoriales que van desde los fundamentos hasta técnicas avanzadas, organizados de forma progresiva.

02

Ejemplos Prácticos

Código real, funcional y listo para copiar en tus proyectos. Aprende haciendo, no solo leyendo.

03

Cheat Sheets

Referencias rápidas de cada tecnología para que puedas consultar sin perder el ritmo de trabajo.

📄HTML5

Tutorial Completo
de HTML5

Aprende la estructura semántica de la web moderna: elementos, formularios, Canvas, multimedia y accesibilidad.

Estructura Básica

Todo documento HTML5 comienza con una declaración DOCTYPE que indica al navegador el tipo de documento. La estructura mínima incluye <html>, <head> y <body>.

HTML
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Descripción de la página">
    <title>Mi página web</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <!-- Contenido de la página -->
    <script src="script.js"></script>
</body>
</html>

Elementos Semánticos

HTML5 introdujo elementos semánticos que describen su contenido con claridad, mejorando la accesibilidad y el SEO.

HTML
<header>
    <nav>Navegación principal</nav>
</header>

<main>
    <article>
        <header>
            <h1>Título del artículo</h1>
            <time datetime="2026-01-15">15 enero 2026</time>
        </header>
        <section>
            <h2>Sección 1</h2>
            <p>Contenido...</p>
        </section>
        <aside>Contenido relacionado</aside>
    </article>
</main>

<footer>Pie de página</footer>

Buenas prácticas semánticas

  • Usa <article> para contenido independiente y reutilizable
  • Usa <section> para agrupar contenido temáticamente relacionado
  • Usa <aside> para contenido complementario o barras laterales
  • Solo debe haber un <main> por página

Formularios HTML5

HTML5 añadió nuevos tipos de input y atributos de validación que mejoran la experiencia del usuario sin JavaScript.

HTML
<form action="/enviar" method="POST">
    <!-- Texto con validación -->
    <input type="text"
           name="nombre"
           required
           minlength="3"
           placeholder="Tu nombre">

    <!-- Email con validación automática -->
    <input type="email" name="email" required>

    <!-- Número con rango -->
    <input type="number" name="edad" min="18" max="99">

    <!-- Fecha -->
    <input type="date" name="fecha" min="2026-01-01">

    <!-- Rango (slider) -->
    <input type="range" name="nivel" min="1" max="10" value="5">

    <!-- Select con búsqueda (datalist) -->
    <input list="tecnologias" name="tech">
    <datalist id="tecnologias">
        <option value="HTML5">
        <option value="CSS3">
        <option value="JavaScript">
    </datalist>

    <button type="submit">Enviar</button>
</form>

Audio y Video

HTML5 permite embeber audio y video de forma nativa sin plugins externos.

HTML
<!-- Video con múltiples formatos -->
<video controls width="800" poster="thumbnail.jpg">
    <source src="video.webm" type="video/webm">
    <source src="video.mp4"  type="video/mp4">
    <p>Tu navegador no soporta HTML5 video.</p>
</video>

<!-- Audio -->
<audio controls>
    <source src="audio.ogg" type="audio/ogg">
    <source src="audio.mp3" type="audio/mpeg">
</audio>

<!-- Figura con caption -->
<figure>
    <img src="foto.jpg"
         alt="Descripción accesible"
         loading="lazy"
         width="800" height="600">
    <figcaption>Pie de foto descriptivo</figcaption>
</figure>

Canvas API

El elemento <canvas> permite dibujar gráficos, animaciones y juegos directamente con JavaScript.

HTML + JS
<canvas id="miCanvas" width="500" height="300"></canvas>

<script>
const canvas = document.getElementById('miCanvas');
const ctx = canvas.getContext('2d');

// Rectángulo
ctx.fillStyle = '#b8ff57';
ctx.fillRect(20, 20, 150, 80);

// Círculo
ctx.beginPath();
ctx.arc(250, 150, 60, 0, Math.PI * 2);
ctx.fillStyle = '#4df0ff';
ctx.fill();

// Texto
ctx.font = 'bold 24px monospace';
ctx.fillStyle = '#0b0c0f';
ctx.fillText('Canvas!', 200, 160);

// Línea
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(500, 300);
ctx.strokeStyle = '#ff6b2b';
ctx.lineWidth = 3;
ctx.stroke();
</script>

Accesibilidad (A11y)

La accesibilidad no es opcional. Usar ARIA roles y atributos correctamente permite que tu web sea usable por todos.

HTML
<!-- Roles ARIA -->
<nav aria-label="Navegación principal">
    <ul role="list">
        <li><a href="/" aria-current="page">Inicio</a></li>
    </ul>
</nav>

<!-- Botón accesible -->
<button aria-label="Cerrar menú"
        aria-expanded="true"
        aria-controls="menu-id">
    <svg aria-hidden="true">...</svg>
</button>

<!-- Formulario accesible -->
<label for="email">Correo electrónico</label>
<input id="email"
       type="email"
       aria-required="true"
       aria-describedby="email-help">
<span id="email-help">Usaremos tu email solo para...</span>
ℹ️

Regla de oro

Si usas un elemento HTML semántico correcto, raramente necesitarás ARIA. Usa <button> para botones, <a> para enlaces, y <nav> para navegación.

🎨CSS3

Tutorial Completo
de CSS3

Domina selectores, box model, flexbox, grid, animaciones y diseño responsive para cualquier dispositivo.

Selectores CSS

Los selectores son patrones que permiten apuntar a elementos HTML para aplicarles estilos. CSS3 ofrece una amplia variedad para un control preciso.

CSS
/* Selector de elemento */
p { color: #f0eee8; }

/* Selector de clase */
.highlight { background: rgba(184, 255, 87, 0.2); }

/* Selector de ID */
#header { font-size: 24px; }

/* Descendiente */
nav a { text-decoration: none; }

/* Hijo directo */
ul > li { list-style: none; }

/* Pseudo-clases */
a:hover { color: #b8ff57; }
button:focus-visible { outline: 2px solid #4df0ff; }
li:nth-child(odd) { background: rgba(255,255,255,0.03); }

/* Pseudo-elementos */
p::first-line { font-weight: 600; }
.quote::before { content: '"'; color: #b8ff57; }

/* Selector de atributo */
input[type="email"] { border-color: #4df0ff; }
a[href^="https"] { /* Externos */ }

Box Model

Todo elemento HTML es una caja. El box model describe cómo se calculan sus dimensiones: contenido, padding, borde y margen. Usar box-sizing: border-box simplifica enormemente los cálculos de layout.

CSS
/* Reset universal — buena práctica */
*, *::before, *::after {
    box-sizing: border-box;
}

.card {
    width: 320px;        /* Ancho del contenido */
    padding: 24px;       /* Espacio interior */
    border: 1px solid rgba(255,255,255,0.1);
    margin: 16px;        /* Espacio exterior */

    /* Con border-box: width=320px INCLUYE padding y border */
}

/* Colapso de márgenes */
.elemento-1 { margin-bottom: 32px; }
.elemento-2 { margin-top: 16px; }
/* Resultado: 32px (el mayor), no 48px */

Flexbox

Flexbox es un sistema de layout unidimensional ideal para alinear elementos en filas o columnas. Perfecto para componentes y layouts de una dimensión.

CSS
/* Contenedor Flex */
.nav {
    display: flex;
    justify-content: space-between;  /* Eje principal */
    align-items: center;             /* Eje cruzado */
    gap: 16px;
    flex-wrap: wrap;                 /* Múltiples líneas */
}

/* Propiedades de los hijos */
.nav-item {
    flex: 1;              /* grow:1, shrink:1, basis:0 */
    flex: 0 0 200px;      /* No crece, no encoge, 200px */
}

/* Centrar perfectamente */
.centrado {
    display: flex;
    justify-content: center;
    align-items: center;
}

/* Orden sin cambiar el DOM */
.importante { order: -1; }  /* Primero visualmente */
💡

Flex vs Grid

Usa Flexbox para layouts de una sola dimensión (fila O columna). Usa Grid para layouts bidimensionales (filas Y columnas).

CSS Grid

Grid es el sistema de layout más potente de CSS. Permite crear layouts bidimensionales complejos con control total sobre filas y columnas.

CSS
/* Grid básico */
.galeria {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
}

/* Grid responsivo sin media queries */
.cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 24px;
}

/* Áreas nombradas */
.layout {
    display: grid;
    grid-template-areas:
        "header  header  header"
        "sidebar main    main"
        "footer  footer  footer";
    grid-template-columns: 240px 1fr 1fr;
    grid-template-rows: 64px 1fr 80px;
    min-height: 100vh;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }
.footer  { grid-area: footer; }

/* Span de celdas */
.featured {
    grid-column: 1 / 3;   /* Ocupa columnas 1 y 2 */
    grid-row: span 2;      /* Ocupa 2 filas */
}

Animaciones y Transiciones

CSS3 permite crear animaciones fluidas y microinteracciones sin JavaScript, usando transiciones para cambios de estado y @keyframes para animaciones complejas.

CSS
/* Transiciones */
.btn {
    background: #b8ff57;
    transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1),
                box-shadow 0.25s ease;
}

.btn:hover {
    transform: translateY(-3px);
    box-shadow: 0 12px 30px rgba(184, 255, 87, 0.4);
}

/* Keyframes — animación de entrada */
@keyframes slideInUp {
    from { opacity: 0; transform: translateY(32px); }
    to   { opacity: 1; transform: translateY(0); }
}

.card {
    animation: slideInUp 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

/* Delay escalonado */
.card:nth-child(1) { animation-delay: 0ms; }
.card:nth-child(2) { animation-delay: 100ms; }
.card:nth-child(3) { animation-delay: 200ms; }

/* Respetar preferencias del usuario */
@media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.01ms !important; }
}

Responsive Design

El diseño responsive adapta la interfaz a cualquier tamaño de pantalla. Las media queries son la herramienta principal, complementadas con unidades relativas y container queries.

CSS
/* Mobile-first: empezamos con móvil */
.container {
    padding: 16px;
    font-size: 1rem;
}

/* Tablet ≥ 768px */
@media (min-width: 768px) {
    .container { padding: 24px; }
    .grid { grid-template-columns: repeat(2, 1fr); }
}

/* Desktop ≥ 1024px */
@media (min-width: 1024px) {
    .container {
        max-width: 1280px;
        margin: 0 auto;
        padding: 0 32px;
    }
    .grid { grid-template-columns: repeat(3, 1fr); }
}

/* Unidades fluidas */
.hero-title {
    font-size: clamp(2rem, 5vw, 5rem); /* min, preferred, max */
}

/* Container Queries (moderno) */
@container (min-width: 400px) {
    .card { flex-direction: row; }
}
JavaScript

Tutorial Completo
de JavaScript

ES6+, manipulación del DOM, programación asíncrona con Async/Await y consumo de APIs REST modernas.

Variables ES6+

JavaScript moderno usa const para valores que no cambian y let para variables reasignables. Olvida var — tiene comportamientos confusos de hoisting y scope.

JavaScript
// const para referencias inmutables
const nombre = 'Ana';
const config = { debug: true, version: '2.0' };
config.debug = false; // ✅ OK — el objeto puede mutar
// config = {};        // ❌ Error — la referencia es constante

// let para valores reasignables
let contador = 0;
contador++;

// Destructuring — extrae valores elegantemente
const { nombre: userName, edad, ciudad = 'Madrid' } = usuario;
const [primero, segundo, ...resto] = numeros;

// Spread operator
const nuevoObjeto = { ...defaults, ...userConfig };
const array2 = [...array1, nuevoPunto];

// Template literals
const mensaje = `Hola ${userName}, tienes ${edad} años.`;

// Optional chaining — evita errores en cadenas largas
const ciudad = usuario?.direccion?.ciudad ?? 'Sin ciudad';

Funciones Arrow

Las arrow functions tienen una sintaxis más concisa y no crean su propio contexto this.

JavaScript
// Función tradicional vs arrow
function sumar(a, b) { return a + b; }
const sumar = (a, b) => a + b;  // Misma cosa

// Un parámetro: sin paréntesis
const doble = x => x * 2;

// Cuerpo multilínea
const procesarUsuario = (usuario) => {
    const nombreCompleto = `${usuario.nombre} ${usuario.apellido}`;
    return { ...usuario, nombreCompleto };
};

// Parámetros por defecto
const saludar = (nombre = 'Developer', emoji = '👋') => {
    return `${emoji} Hola, ${nombre}!`;
};

// Currying
const multiplicar = (factor) => (numero) => numero * factor;
const triple = multiplicar(3);
triple(5); // 15

Métodos de Arrays

Los métodos funcionales de arrays son la base del JS moderno. Son declarativos, sin mutación y se pueden encadenar.

JavaScript
const productos = [
    { nombre: 'Laptop', precio: 999, stock: 5 },
    { nombre: 'Mouse',  precio: 29,  stock: 0 },
    { nombre: 'Teclado',precio: 79,  stock: 12 },
];

// .filter() — mantiene elementos que cumplan la condición
const conStock = productos.filter(p => p.stock > 0);

// .map() — transforma cada elemento
const nombres = productos.map(p => p.nombre);
const conIVA  = productos.map(p => ({
    ...p, precioFinal: p.precio * 1.21
}));

// .reduce() — acumula en un solo valor
const totalStock = productos.reduce((acc, p) => acc + p.stock, 0);

// Encadenamiento
const totalInversion = productos
    .filter(p => p.stock > 0)
    .reduce((sum, p) => sum + (p.precio * p.stock), 0);

// .some() y .every()
const hayStock      = productos.some(p => p.stock > 0);    // true
const todoConStock  = productos.every(p => p.stock > 0);   // false

Manipulación del DOM

El DOM es la representación del HTML en memoria. JavaScript puede leerlo y modificarlo en tiempo real para crear interfaces interactivas.

JavaScript
// Selección de elementos
const btn   = document.querySelector('#miBoton');
const cards = document.querySelectorAll('.card');

// Leer y modificar atributos/contenido
btn.textContent = 'Nuevo texto';
btn.setAttribute('aria-expanded', 'true');
const valor = btn.dataset.id; // data-id="123"

// Clases
btn.classList.add('activo');
btn.classList.remove('oculto');
btn.classList.toggle('expandido');

// Crear y añadir elementos
const li = document.createElement('li');
li.className = 'lista-item';
li.innerHTML = `<span>${texto}</span>`;
lista.appendChild(li);

// Event listeners con delegación
document.addEventListener('click', (e) => {
    if (e.target.closest('.card')) {
        const card = e.target.closest('.card');
        card.classList.toggle('selected');
    }
});

Async / Await

Async/Await hace que el código asíncrono sea tan legible como el síncrono. Siempre usa try/catch para manejar errores correctamente.

JavaScript
// Función async — siempre retorna una Promise
async function obtenerDatos(userId) {
    try {
        const res = await fetch(`/api/users/${userId}`);
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const usuario = await res.json();
        return usuario;
    } catch (error) {
        console.error('Error:', error.message);
        throw error;
    }
}

// Promesas en paralelo
async function cargarDashboard(userId) {
    const [usuario, posts, notifs] = await Promise.all([
        fetch(`/api/users/${userId}`).then(r => r.json()),
        fetch(`/api/posts?user=${userId}`).then(r => r.json()),
        fetch(`/api/notifications/${userId}`).then(r => r.json()),
    ]);
    return { usuario, posts, notifs };
}

// Promise.allSettled — continúa aunque algunas fallen
const resultados = await Promise.allSettled([api1(), api2(), api3()]);
const exitosos   = resultados.filter(r => r.status === 'fulfilled');

Fetch API

Fetch es la API nativa para hacer peticiones HTTP, basada en Promises y con soporte para todos los métodos HTTP.

JavaScript
// GET — obtener datos
async function getUsers() {
    const res = await fetch('https://api.ejemplo.com/users');
    return res.json();
}

// POST — crear recurso
async function createUser(userData) {
    const res = await fetch('https://api.ejemplo.com/users', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${token}`,
        },
        body: JSON.stringify(userData),
    });
    if (!res.ok) throw new Error(res.statusText);
    return res.json();
}

// PATCH — actualización parcial
async function updateUser(id, changes) {
    const res = await fetch(`/api/users/${id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(changes),
    });
    return res.json();
}

// DELETE
async function deleteUser(id) {
    await fetch(`/api/users/${id}`, { method: 'DELETE' });
}
⚛️React

Tutorial Completo
de React

Componentes funcionales, hooks esenciales, gestión de estado y efectos secundarios para apps modernas.

Componentes React

Los componentes son las unidades fundamentales de React. Son funciones que reciben datos (props) y devuelven JSX. En React moderno, siempre usamos componentes funcionales.

JSX
// Componente funcional — la forma moderna
function Saludo({ nombre }) {
    return <h1>Hola, {nombre}!</h1>;
}

// Arrow function component
const Tarjeta = ({ titulo, descripcion, imagen }) => {
    return (
        <article className="card">
            <img src={imagen} alt={titulo} />
            <h2>{titulo}</h2>
            <p>{descripcion}</p>
        </article>
    );
};

// Uso del componente
function App() {
    return (
        <main>
            <Saludo nombre="Developer" />
            <Tarjeta
                titulo="Mi primera tarjeta"
                descripcion="Descripción aquí"
                imagen="/foto.jpg"
            />
        </main>
    );
}

JSX

JSX es una extensión de JavaScript que permite escribir HTML dentro de JS. Se transpila a llamadas React.createElement() bajo el capó.

JSX
// JSX vs JavaScript puro
const elemento = <h1 className="titulo">Hola Mundo</h1>;
// Equivalente a:
const elemento = React.createElement('h1', { className: 'titulo' }, 'Hola Mundo');

// Expresiones en JSX — dentro de {}
const nombre = 'Ana';
const elemento = <p>Hola {nombre}, son las {new Date().getHours()}h</p>;

// Renderizado condicional
const Alerta = ({ tipo, mensaje }) => (
    <div className={`alerta alerta-${tipo}`}>
        {tipo === 'error' && <span>❌</span>}
        {tipo === 'ok'    && <span>✅</span>}
        {mensaje}
    </div>
);

// Listas con .map() — siempre incluir key única
const Lista = ({ items }) => (
    <ul>
        {items.map(item => (
            <li key={item.id}>{item.nombre}</li>
        ))}
    </ul>
);

Props

Las props son los parámetros de los componentes. Son inmutables — un componente nunca debe modificar sus propias props.

JSX
// Desestructuración de props
function Boton({ children, onClick, variante = 'primary', disabled = false }) {
    return (
        <button
            onClick={onClick}
            disabled={disabled}
            className={`btn btn-${variante}`}
        >
            {children}
        </button>
    );
}

// Props de función (callbacks)
function Formulario({ onSubmit }) {
    const handleSubmit = (e) => {
        e.preventDefault();
        onSubmit({ nombre: 'Ana', email: '[email protected]' });
    };
    return <form onSubmit={handleSubmit}>...</form>;
}

// Spread de props
function Input(props) {
    const { label, ...inputProps } = props;
    return (
        <label>
            {label}
            <input {...inputProps} />
        </label>
    );
}

Estado con useState

El estado permite que los componentes recuerden información entre renders. Cualquier cambio de estado re-renderiza el componente.

JSX
import { useState } from 'react';

function Contador() {
    const [cuenta, setCuenta] = useState(0);

    return (
        <div>
            <p>Cuenta: {cuenta}</p>
            <button onClick={() => setCuenta(c => c + 1)}>+</button>
            <button onClick={() => setCuenta(c => c - 1)}>-</button>
            <button onClick={() => setCuenta(0)}>Reset</button>
        </div>
    );
}

// Estado con objetos
function Formulario() {
    const [form, setForm] = useState({
        nombre: '', email: '', aceptaTerminos: false
    });

    const handleChange = (e) => {
        const { name, value, type, checked } = e.target;
        setForm(prev => ({
            ...prev,
            [name]: type === 'checkbox' ? checked : value
        }));
    };

    return (
        <form>
            <input name="nombre" value={form.nombre} onChange={handleChange} />
            <input name="email"  value={form.email}  onChange={handleChange} />
        </form>
    );
}

Hooks Esenciales

Los hooks permiten usar estado y otras características de React en componentes funcionales. Siempre deben llamarse al nivel superior del componente.

JSX
import { useState, useReducer, useRef, useMemo, useCallback } from 'react';

// useReducer — para estado complejo
function reducer(state, action) {
    switch (action.type) {
        case 'INCREMENT': return { ...state, count: state.count + 1 };
        case 'RESET':     return { count: 0 };
        default: return state;
    }
}

function Componente() {
    const [state, dispatch] = useReducer(reducer, { count: 0 });

    // useRef — acceder al DOM sin re-render
    const inputRef = useRef(null);
    const enfocarInput = () => inputRef.current.focus();

    // useMemo — valor memorizado (performance)
    const totalFiltrado = useMemo(() =>
        items.filter(i => i.activo).reduce((s, i) => s + i.precio, 0),
        [items]
    );

    // useCallback — función memorizada
    const handleClick = useCallback(() => {
        dispatch({ type: 'INCREMENT' });
    }, []);

    return <button onClick={handleClick}>{state.count}</button>;
}

useEffect

useEffect maneja efectos secundarios: peticiones a APIs, subscripciones, timers, y manipulación del DOM. El array de dependencias controla cuándo se ejecuta.

JSX
import { useState, useEffect } from 'react';

function PerfilUsuario({ userId }) {
    const [usuario, setUsuario]   = useState(null);
    const [cargando, setCargando] = useState(true);
    const [error, setError]       = useState(null);

    useEffect(() => {
        // AbortController para cancelar peticiones al desmontar
        const controller = new AbortController();

        async function cargarUsuario() {
            try {
                setCargando(true);
                const res = await fetch(`/api/users/${userId}`, {
                    signal: controller.signal
                });
                const data = await res.json();
                setUsuario(data);
            } catch (err) {
                if (err.name !== 'AbortError') setError(err.message);
            } finally {
                setCargando(false);
            }
        }

        cargarUsuario();

        // Cleanup — se ejecuta al desmontar o cuando userId cambia
        return () => controller.abort();
    }, [userId]); // Se re-ejecuta cuando userId cambia

    if (cargando) return <div>Cargando...</div>;
    if (error)    return <div>Error: {error}</div>;
    return <div>{usuario?.nombre}</div>;
}
📋Referencia rápida

Cheat Sheets

Referencia rápida de HTML5, CSS3, JavaScript y React. Todo lo que necesitas, cuando lo necesitas.

HTML5

Estructura básica<!DOCTYPE html>
Encabezados<h1> … <h6>
Enlace<a href="url">texto</a>
Imagen<img src="" alt="" loading="lazy">
Lista no ordenada<ul><li>item</li></ul>
Tabla<table><tr><td></td></tr></table>
Formulario<form action="" method="POST">
Input tipo email<input type="email" required>
Semántica — nav<nav aria-label="...">
Semántica — main<main> (único por página)
Canvas<canvas id="" width="" height="">
Video<video controls src=""></video>

CSS3

Reset universal*, *::before, *::after { box-sizing: border-box }
Flexbox centradodisplay: flex; justify-content: center; align-items: center
Grid auto-fitgrid-template-columns: repeat(auto-fit, minmax(280px, 1fr))
Fuente fluidafont-size: clamp(1rem, 2.5vw, 2rem)
Transición suavetransition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1)
Variable CSS--color-primary: #b8ff57; color: var(--color-primary)
Media query móvil@media (max-width: 768px) { ... }
Pseudo-elemento.el::before { content: ''; display: block }
Overlayposition: absolute; inset: 0; background: rgba(0,0,0,.5)
Truncar textooverflow: hidden; text-overflow: ellipsis; white-space: nowrap
Aspect ratioaspect-ratio: 16 / 9
Backdrop blurbackdrop-filter: blur(20px) saturate(180%)

JavaScript

Seleccionar elementodocument.querySelector('.clase')
Escuchar eventoel.addEventListener('click', handler)
Toggle claseel.classList.toggle('activo')
Fetch GETconst data = await fetch(url).then(r => r.json())
Destructuringconst { nombre, edad = 0 } = objeto
Spreadconst nuevo = { ...original, extra: true }
Optional chaininguser?.address?.city ?? 'N/A'
Array filter + maparr.filter(x => x.activo).map(x => x.nombre)
Promise.allconst [a, b] = await Promise.all([p1, p2])
LocalStoragelocalStorage.setItem('key', JSON.stringify(val))
Template literal`Hola ${nombre}, tienes ${edad} años`
Arrow functionconst fn = (x) => x * 2

React

Componente funcionalconst Comp = ({ prop }) => <div>{prop}</div>
useStateconst [val, setVal] = useState(inicial)
Actualizar estadosetVal(prev => prev + 1)
useEffectuseEffect(() => { /* efecto */ }, [dep])
useRefconst ref = useRef(null); ref.current.focus()
useMemoconst val = useMemo(() => compute(), [dep])
useCallbackconst fn = useCallback(() => {}, [dep])
Renderizado listaitems.map(i => <li key={i.id}>{i.name}</li>)
Condicional{activo && <span>Activo</span>}
Evento handler<button onClick={() => doSomething()}>
className dinámicoclassName={`base ${activo ? 'activo' : ''}`}
Props spread<Input {...props} />
🔒Legal

Política de
Privacidad

Última actualización: 20 de febrero de 2026

🍪Legal

Política de
Cookies

Última actualización: 20 de febrero de 2026