El sistema de componentes UI de Ionic
Ionic ofrece un conjunto de componentes web (prefijo ion-) que ya incluyen estilos, animaciones, comportamiento táctil y adaptación a iOS/Android. La idea es componer pantallas a partir de contenedores (estructura), barras (navegación/acciones), componentes de contenido (listas, tarjetas), formularios (entrada de datos) y un sistema de grid para maquetación responsive.
Contenedores principales
<ion-app>: raíz de la app (normalmente ya viene en el proyecto).<ion-page>: contenedor de una pantalla; ayuda a gestionar transiciones y scroll.<ion-header>,<ion-content>,<ion-footer>: estructura típica de una página.
En la práctica, casi todas las pantallas se organizan como: header (barra superior), content (contenido con scroll) y opcionalmente footer (acciones persistentes).
Barras: toolbar, title y botones
Para una barra superior consistente se usa <ion-toolbar> dentro de <ion-header>. Puedes colocar título y botones en “slots” (zonas) como start y end.
<ion-header> <ion-toolbar> <ion-buttons slot="start"> <ion-button>Atrás</ion-button> </ion-buttons> <ion-title>Perfil</ion-title> <ion-buttons slot="end"> <ion-button fill="clear">Guardar</ion-button> </ion-buttons> </ion-toolbar></ion-header>Recomendación: usa ion-title para mantener alineación y tamaños correctos según plataforma.
Listas y elementos
Las listas en Ionic se construyen con <ion-list> y <ion-item>. Un ion-item puede contener texto, iconos, toggles, inputs, etc. Para navegación, es común usar button y detail (flecha) en el item.
- Escuche el audio con la pantalla apagada.
- Obtenga un certificado al finalizar.
- ¡Más de 5000 cursos para que explores!
Descargar la aplicación
<ion-list> <ion-item button detail> <ion-label>Notificaciones</ion-label> </ion-item> <ion-item> <ion-label>Modo oscuro</ion-label> <ion-toggle slot="end"></ion-toggle> </ion-item></ion-list>Tarjetas (cards)
Las tarjetas ayudan a agrupar información y acciones. Úsalas para bloques de contenido con jerarquía visual clara.
<ion-card> <ion-card-header> <ion-card-title>Plan Pro</ion-card-title> <ion-card-subtitle>Mensual</ion-card-subtitle> </ion-card-header> <ion-card-content>Acceso a funciones avanzadas y soporte prioritario.</ion-card-content></ion-card>Formularios: inputs, selects y validación visual
Para formularios, combina ion-item + ion-label + ion-input/ion-select. Esto asegura alineación, espaciado y accesibilidad base.
<ion-item> <ion-label position="stacked">Email</ion-label> <ion-input type="email" autocomplete="email" inputmode="email"></ion-input></ion-item>Grid responsive: filas y columnas
El grid de Ionic se basa en ion-grid, ion-row y ion-col. Puedes definir tamaños por breakpoint (por ejemplo, size, size-md, size-lg) para adaptar el layout.
<ion-grid> <ion-row> <ion-col size="12" size-md="6">Col A</ion-col> <ion-col size="12" size-md="6">Col B</ion-col> </ion-row></ion-grid>Guía práctica: construir una pantalla completa paso a paso
Vamos a crear una pantalla tipo “Editar perfil” que incluya: barra superior, avatar, tarjeta con información, formulario, lista de preferencias y un footer con acción principal. El objetivo es practicar estructura semántica, utilidades, estilos por componente, variables CSS, accesibilidad y responsive.
Paso 1: estructura base de la página
Empieza con una estructura clara: header (navegación), content (scroll) y footer (acción). Dentro del contenido, usa secciones lógicas (aunque Ionic no obliga, es buena práctica).
<ion-page> <ion-header> <ion-toolbar> <ion-title>Editar perfil</ion-title> <ion-buttons slot="end"> <ion-button fill="clear">Guardar</ion-button> </ion-buttons> </ion-toolbar> </ion-header> <ion-content fullscreen> <main class="page"> <section class="page__hero" aria-label="Información principal"></section> <section class="page__form" aria-label="Datos del perfil"></section> <section class="page__prefs" aria-label="Preferencias"></section> </main> </ion-content> <ion-footer> <ion-toolbar> <ion-button expand="block">Guardar cambios</ion-button> </ion-toolbar> </ion-footer></ion-page>Notas: <main> y <section> aportan semántica. Los aria-label ayudan a lectores de pantalla a identificar regiones.
Paso 2: construir el “hero” con avatar y resumen
Usa componentes de Ionic para mantener consistencia visual: ion-avatar, ion-item e ion-label. Para alinear, puedes apoyarte en CSS propio y utilidades.
<section class="page__hero" aria-label="Información principal"> <ion-card> <ion-card-content> <div class="hero"> <ion-avatar class="hero__avatar"> <img alt="Foto de perfil" src="assets/avatar.jpg" /> </ion-avatar> <div class="hero__meta"> <p class="hero__name">María López</p> <p class="hero__hint">Actualiza tus datos y preferencias</p> </div> </div> </ion-card-content> </ion-card></section>Accesibilidad: el alt del avatar debe describir la imagen. Si fuera decorativa, usarías alt="".
Paso 3: formulario con labels correctos y tamaños táctiles
En móviles, los campos deben ser fáciles de tocar. Ionic ya ofrece alturas adecuadas, pero asegúrate de no reducirlas con CSS. Usa position="stacked" para labels visibles y claras.
<section class="page__form" aria-label="Datos del perfil"> <ion-list inset> <ion-item> <ion-label position="stacked">Nombre</ion-label> <ion-input type="text" autocomplete="name"></ion-input> </ion-item> <ion-item> <ion-label position="stacked">Email</ion-label> <ion-input type="email" autocomplete="email" inputmode="email"></ion-input> </ion-item> <ion-item> <ion-label position="stacked">País</ion-label> <ion-select interface="popover" placeholder="Selecciona"> <ion-select-option value="es">España</ion-select-option> <ion-select-option value="mx">México</ion-select-option> <ion-select-option value="ar">Argentina</ion-select-option> </ion-select> </ion-item> </ion-list></section>Accesibilidad: mantener el label visible evita depender solo de placeholders (que pueden tener bajo contraste y desaparecen al escribir). Además, autocomplete mejora la experiencia.
Paso 4: preferencias como lista con toggles
Para preferencias, una lista es más escaneable. Coloca el control en slot="end" y deja el texto como ion-label.
<section class="page__prefs" aria-label="Preferencias"> <ion-list inset> <ion-item> <ion-label>Recibir novedades</ion-label> <ion-toggle slot="end"></ion-toggle> </ion-item> <ion-item> <ion-label>Notificaciones push</ion-label> <ion-toggle slot="end"></ion-toggle> </ion-item> </ion-list></section>Accesibilidad: el texto del ion-label describe el propósito del toggle. Evita etiquetas genéricas como “Activar”.
Paso 5: maquetación con grid para adaptar a pantallas grandes
En móviles, suele ser una columna. En tablets/desktop, puedes mostrar el formulario y preferencias en dos columnas. Envuelve las secciones en un grid y asigna tamaños por breakpoint.
<ion-content fullscreen> <main class="page"> <section class="page__hero" aria-label="Información principal">...</section> <ion-grid fixed> <ion-row> <ion-col size="12" size-lg="7"> <section class="page__form" aria-label="Datos del perfil">...</section> </ion-col> <ion-col size="12" size-lg="5"> <section class="page__prefs" aria-label="Preferencias">...</section> </ion-col> </ion-row> </ion-grid> </main></ion-content>fixed ayuda a limitar el ancho máximo en pantallas grandes para mejorar legibilidad.
Clases/utilidades y estilos: globales vs. por componente
Cuándo usar estilos por componente
Si un estilo solo aplica a una pantalla o componente, colócalo en el archivo de estilos de ese componente (por ejemplo, page.scss). Esto evita efectos colaterales.
/* Estilos del componente/página */.page { padding: 12px;}.hero { display: flex; gap: 12px; align-items: center;}.hero__avatar { width: 64px; height: 64px;}.hero__name { margin: 0; font-weight: 700; font-size: 1.05rem;}.hero__hint { margin: 2px 0 0; color: var(--ion-color-medium); font-size: 0.9rem;}Cuándo usar estilos globales
Usa estilos globales para reglas transversales: tipografía base, espaciados comunes, ajustes de tema o clases utilitarias reutilizables. En Ionic, esto suele vivir en archivos globales de estilos.
/* Utilidad reutilizable */.stack-sm > * + * { margin-top: 8px;}/* Mejoras generales de legibilidad */:root { --app-max-text-width: 68ch;}main.page { max-width: var(--app-max-text-width); margin: 0 auto;}Evita sobreescribir estilos internos de ion-* de forma agresiva. Prefiere variables CSS y propiedades expuestas por los componentes.
Variables CSS y theming básico
Ionic se apoya en variables CSS para colores, tipografía y espaciado. Esto permite cambiar el “tema” sin reescribir componentes. Un enfoque típico es ajustar colores principales y el fondo/contraste.
Colores de marca
Puedes definir un color personalizado y usarlo con color="primary" o creando un nuevo token. Ejemplo de ajuste del primario (conceptual):
:root { --ion-color-primary: #3b82f6; --ion-color-primary-rgb: 59,130,246; --ion-color-primary-contrast: #ffffff; --ion-color-primary-contrast-rgb: 255,255,255; --ion-color-primary-shade: #3472d8; --ion-color-primary-tint: #4f8ff7;}Accesibilidad: asegúrate de que el color de contraste sea legible (texto sobre botones, chips, etc.). Si dudas, prioriza texto blanco sobre colores oscuros y texto negro sobre fondos claros.
Estilos por componente usando variables expuestas
Muchos componentes permiten ajustar partes visuales con variables. Por ejemplo, en un ion-card puedes modificar el radio o el fondo desde CSS del componente:
ion-card { --border-radius: 16px; --background: var(--ion-color-light);}Este enfoque es más estable que intentar apuntar a elementos internos del Shadow DOM.
Accesibilidad práctica en Ionic UI
Labels y ayudas de texto
- Prefiere
ion-labelvisible (stacked o floating) en inputs. - Usa textos de ayuda cuando el formato sea importante (por ejemplo, “Usa un email válido”).
- Si muestras errores, acompáñalos de texto (no solo color) y colócalos cerca del campo.
<ion-item> <ion-label position="stacked">Email</ion-label> <ion-input type="email"></ion-input></ion-item><ion-text color="danger"> <p class="field-error">Introduce un email válido.</p></ion-text>Contraste y estados
- No dependas solo del color para indicar estado (error/éxito). Añade iconos o texto.
- Evita grises demasiado claros para texto secundario; prueba en brillo bajo.
Tamaños táctiles
- Botones principales con
expand="block"facilitan el toque. - No reduzcas la altura de
ion-item,ion-buttonoion-inputpor debajo de lo cómodo. - Deja espacio entre acciones destructivas y acciones primarias.
Orden y semántica
- Usa
<main>para el contenido principal y<section>para agrupar. - Si un
ion-itemnavega, usabuttonpara que sea accesible como control. - Proporciona
alten imágenes informativas.
Checklist rápido de adaptación a distintos tamaños
| Objetivo | Qué usar | Ejemplo |
|---|---|---|
| Una columna en móvil, dos en desktop | ion-grid + ion-col size-lg | size="12" size-lg="6" |
| Limitar ancho para legibilidad | ion-grid fixed o max-width en contenedor | max-width: 68ch |
| Espaciado consistente | Clases utilitarias propias | .stack-sm |
| Acción principal siempre visible | ion-footer con botón | expand="block" |