En este tutorial, aprenderemos a usar el componente ion-modal
en Ionic, junto con su complemento ion-backdrop
para crear modales que se sobreponen a la interfaz principal, de forma estilizada y personalizada.
Contenido del Tutorial
- Introducción a
ion-modal
yion-backdrop
- Configuración básica de un modal
- Personalización del modal con CSS (agregar degradado)
- Uso de
ion-backdrop
y cómo aplicarlo para un efecto visual - Cómo abrir y cerrar el modal
- Interacción del usuario: botón de cierre y fondo reactivo
- Ejemplo completo en código
Paso 1: Comprender los Componentes ion-modal
e ion-backdrop
ion-modal
: Un modal es una ventana emergente que se muestra encima del contenido principal de la app. Ionic ofreceion-modal
como una forma fácil de implementar estas ventanas flotantes. Es ideal para mostrar información adicional sin cambiar de página, o para realizar acciones específicas sin salir de la vista actual.ion-backdrop
: Este componente crea un fondo oscuro detrás del modal o cualquier otro elemento superpuesto. Ayuda a desviar la atención del usuario hacia el modal, ya que el fondo se vuelve oscuro o difuminado.ion-backdrop
también puede configurarse para cerrar el modal si se hace clic fuera de él.
Paso 2: Crear una Aplicación Básica en Ionic
Si aún no tienes una aplicación, comienza creando una nueva aplicación en Ionic. Abre tu terminal y escribe:
ionic start ModalExampleApp blank --type=angular
cd ModalExampleApp
Esto creará una nueva aplicación llamada «ModalExampleApp» con una plantilla en blanco.
Paso 3: Configurar ion-modal
en la Página
- Dirígete a
src/app/home/home.page.html
y agrega el código para el modal. - Coloca un botón en la página principal (
home.page.html
) que abrirá el modal. Agrega también el modal en sí:
<ion-header>
<ion-toolbar>
<ion-title>Modal Example</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<!-- Botón que abrirá el modal -->
<ion-button expand="full" (click)="openModal()">Abrir Modal</ion-button>
<!-- Componente Modal -->
<ion-modal #myModal>
<ng-template>
<ion-header>
<ion-toolbar color="primary">
<ion-title>Mi Modal</ion-title>
<ion-buttons slot="end">
<ion-button (click)="closeModal()">Cerrar</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<p>Este es el contenido del modal.</p>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>
Explicación del Código:
ion-button (click)="openModal()"
: Este botón dispara el métodoopenModal()
en el archivo de TypeScript para abrir el modal.ion-modal
: Aquí es donde creamos el componenteion-modal
. El contenido del modal está en una plantilla<ng-template>
, que se renderizará dentro del modal.closeModal()
: En el encabezado del modal, incluimos un botón para cerrarlo, que llama al métodocloseModal()
.
Paso 4: Agregar Funciones para Abrir y Cerrar el Modal en TypeScript
- Abre
home.page.ts
y crea los métodosopenModal()
ycloseModal()
para manejar la apertura y cierre del modal.
import { Component } from '@angular/core';
import { ModalController } from '@ionic/angular';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
constructor(private modalController: ModalController) {}
async openModal() {
const modal = await this.modalController.create({
component: ModalContentComponent,
cssClass: 'my-custom-modal-css'
});
return await modal.present();
}
async closeModal() {
await this.modalController.dismiss();
}
}
Explicación del Código:
ModalController
: Es un servicio de Ionic que controla la apertura y cierre de los modales.create()
: Este método crea el modal y permite configurarlo, como asociarlo a una clase CSS personalizada.dismiss()
: Cierra el modal.
Nota: Necesitamos crear el componente
ModalContentComponent
para que funcione correctamente. Vamos a configurarlo en el siguiente paso.
Paso 5: Crear el Componente del Contenido del Modal
- Genera un nuevo componente para el contenido del modal. En la terminal, escribe:
ionic generate component ModalContent
Esto creará un nuevo componente llamado ModalContent
en src/app/modal-content/
.
- Edita el archivo
modal-content.component.html
con el contenido que quieras mostrar en el modal:
<ion-header>
<ion-toolbar color="secondary">
<ion-title>Contenido del Modal</ion-title>
<ion-buttons slot="end">
<ion-button (click)="dismiss()">Cerrar</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<h2>¡Bienvenido al Modal!</h2>
<p>Este es un contenido de ejemplo dentro del modal.</p>
</ion-content>
- Agrega el método
dismiss()
enmodal-content.component.ts
para cerrar el modal:
import { Component } from '@angular/core';
import { ModalController } from '@ionic/angular';
@Component({
selector: 'app-modal-content',
templateUrl: './modal-content.component.html',
styleUrls: ['./modal-content.component.scss'],
})
export class ModalContentComponent {
constructor(private modalController: ModalController) {}
dismiss() {
this.modalController.dismiss();
}
}
Explicación del Código:
dismiss()
: Llama aModalController.dismiss()
para cerrar el modal. Así, el usuario puede cerrar el modal usando el botón «Cerrar» en el encabezado.
Paso 6: Personalizar el Estilo del Modal con Degradados en CSS
- Abre
global.scss
omodal-content.component.scss
para aplicar estilos personalizados, como un fondo degradado, al modal. - Agrega el siguiente código para un degradado de fondo en el modal:
.my-custom-modal-css {
--background: linear-gradient(135deg, #4e54c8, #8f94fb);
color: white;
border-radius: 12px;
margin: 16px;
}
.my-custom-modal-css .ion-header {
background-color: rgba(0, 0, 0, 0.1);
}
.my-custom-modal-css .ion-content {
padding: 20px;
}
- Explicación del Código:
--background
: Aplica un fondo degradado a todo el modal.border-radius
ymargin
: Hacen que el modal tenga bordes redondeados y un margen para que no ocupe todo el ancho de la pantalla.
A continuacion, vamos a añadir algunas animaciones para que el modal tenga un toque más dinámico y atractivo al abrirse y cerrarse. Ionic permite configurar animaciones personalizadas en ion-modal
mediante el uso de enterAnimation
y leaveAnimation
. Para eso veremos cómo aplicar animaciones de entrada y salida, y luego personalizaremos estas animaciones.
Animaciones Personalizadas para el ion-modal
Las animaciones ayudan a hacer que la experiencia de usuario sea más agradable y visualmente atractiva. Aquí explicaremos cómo añadir animaciones de entrada y salida a un ion-modal
, desde opciones de movimiento hasta efectos de desvanecimiento.
1. Crear Funciones de Animación Personalizadas
Para definir las animaciones de entrada y salida, primero crearemos funciones personalizadas en el archivo home.page.ts
.
A continuación, implementaremos animaciones para:
- Deslizar el modal desde abajo (entrada)
- Deslizar el modal hacia abajo (salida)
Veamos cómo hacerlo.
Paso 1: Definir la Animación de Entrada
Agrega el siguiente código en home.page.ts
para configurar una animación de entrada que desliza el modal desde la parte inferior de la pantalla:
import { AnimationController, ModalController } from '@ionic/angular';
import { Component } from '@angular/core';
import { ModalContentComponent } from '../modal-content/modal-content.component';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
constructor(
private modalController: ModalController,
private animationCtrl: AnimationController
) {}
async openModal() {
const modal = await this.modalController.create({
component: ModalContentComponent,
cssClass: 'my-custom-modal-css',
enterAnimation: this.enterAnimation,
leaveAnimation: this.leaveAnimation,
});
return await modal.present();
}
enterAnimation(baseEl: HTMLElement) {
const backdropAnimation = this.animationCtrl
.create()
.addElement(baseEl.querySelector('ion-backdrop')!)
.fromTo('opacity', '0.01', 'var(--backdrop-opacity)');
const wrapperAnimation = this.animationCtrl
.create()
.addElement(baseEl.querySelector('.modal-wrapper')!)
.keyframes([
{ offset: 0, opacity: '0', transform: 'translateY(100%)' },
{ offset: 1, opacity: '1', transform: 'translateY(0)' },
]);
return this.animationCtrl
.create()
.addElement(baseEl)
.easing('ease-out')
.duration(500)
.addAnimation([backdropAnimation, wrapperAnimation]);
}
leaveAnimation(baseEl: HTMLElement) {
const backdropAnimation = this.animationCtrl
.create()
.addElement(baseEl.querySelector('ion-backdrop')!)
.fromTo('opacity', 'var(--backdrop-opacity)', '0');
const wrapperAnimation = this.animationCtrl
.create()
.addElement(baseEl.querySelector('.modal-wrapper')!)
.keyframes([
{ offset: 0, opacity: '1', transform: 'translateY(0)' },
{ offset: 1, opacity: '0', transform: 'translateY(100%)' },
]);
return this.animationCtrl
.create()
.addElement(baseEl)
.easing('ease-in')
.duration(500)
.addAnimation([backdropAnimation, wrapperAnimation]);
}
async closeModal() {
await this.modalController.dismiss();
}
}
Explicación del Código
enterAnimation
: Define la animación de entrada. Desliza el modal desde la parte inferior de la pantalla con una duración de 500 ms.leaveAnimation
: Define la animación de salida. Desliza el modal hacia la parte inferior, aplicando el mismo tiempo de duración.AnimationController
: Es el controlador que maneja las animaciones en Ionic y permite combinar múltiples efectos, como el cambio de opacidad y el desplazamiento vertical.
2. Aplicar Animaciones de Desvanecimiento
Otra opción es agregar una animación de desvanecimiento, donde el modal aparecerá y desaparecerá suavemente en la pantalla.
Para ello, modifica las funciones de animación en home.page.ts
de la siguiente manera:
enterAnimation(baseEl: HTMLElement) {
return this.animationCtrl
.create()
.addElement(baseEl.querySelector('.modal-wrapper')!)
.fromTo('opacity', '0', '1')
.duration(400)
.easing('ease-in');
}
leaveAnimation(baseEl: HTMLElement) {
return this.animationCtrl
.create()
.addElement(baseEl.querySelector('.modal-wrapper')!)
.fromTo('opacity', '1', '0')
.duration(400)
.easing('ease-out');
}
Esta configuración crea una transición suave de opacidad, con una duración de 400 ms tanto para la entrada como para la salida.
3. Combinar Animaciones de Desplazamiento y Desvanecimiento
Para un efecto más complejo, puedes combinar ambas animaciones para que el modal se deslice y se desvanezca al mismo tiempo.
Actualiza el código de animación en home.page.ts
de esta forma:
enterAnimation(baseEl: HTMLElement) {
return this.animationCtrl
.create()
.addElement(baseEl.querySelector('.modal-wrapper')!)
.keyframes([
{ offset: 0, opacity: '0', transform: 'translateY(100%)' },
{ offset: 1, opacity: '1', transform: 'translateY(0)' },
])
.duration(500)
.easing('ease-out');
}
leaveAnimation(baseEl: HTMLElement) {
return this.animationCtrl
.create()
.addElement(baseEl.querySelector('.modal-wrapper')!)
.keyframes([
{ offset: 0, opacity: '1', transform: 'translateY(0)' },
{ offset: 1, opacity: '0', transform: 'translateY(100%)' },
])
.duration(500)
.easing('ease-in');
}
Explicación de las Keyframes
offset
: Define el punto en el que ocurre la animación.0
es el inicio y1
es el final.transform: translateY(100%)
: Hace que el modal comience fuera de la pantalla (hacia abajo) y luego se mueva hacia su posición inicial.opacity
: Comienza desde 0 (invisible) y va hacia 1 (visible), para un efecto de desvanecimiento.
4. Estilizar el ion-backdrop
y Configurar su Interacción
Para mejorar el aspecto de ion-backdrop
y hacerlo parte integral de la experiencia visual del modal, agrega estos estilos personalizados.
- Abre
global.scss
y añade estilos para que el fondo oscuro tenga un efecto de opacidad más sutil y agradable:
ion-backdrop {
--backdrop-opacity: 0.4;
}
Este ajuste hace que el fondo oscuro detrás del modal sea un poco más claro, permitiendo que el contenido de la pantalla principal sea visible, pero sin distraer del modal.
- Permitir Cerrar el Modal al Tocar el Fondo En la configuración de
openModal
, podemos permitir que el usuario cierre el modal haciendo clic fuera de él:
async openModal() {
const modal = await this.modalController.create({
component: ModalContentComponent,
cssClass: 'my-custom-modal-css',
enterAnimation: this.enterAnimation,
leaveAnimation: this.leaveAnimation,
backdropDismiss: true, // Habilita el cierre al tocar fuera del modal
});
return await modal.present();
}
backdropDismiss: true
: Configura el modal para cerrarse automáticamente si el usuario toca elion-backdrop
, lo cual es útil para mejorar la experiencia de usuario.
Ejemplo Completo del Código en home.page.ts
Aquí tienes el código completo con las animaciones de entrada y salida, el uso de backdropDismiss
, y la personalización del fondo.
import { AnimationController, ModalController } from '@ionic/angular';
import { Component } from '@angular/core';
import { ModalContentComponent } from '../modal-content/modal-content.component';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
constructor(
private modalController: ModalController,
private animationCtrl: AnimationController
) {}
async openModal() {
const modal = await this.modalController.create({
component: ModalContentComponent,
cssClass: 'my-custom-modal-css',
enterAnimation: this.enterAnimation,
leaveAnimation: this.leaveAnimation,
backdropDismiss: true,
});
return await modal.present();
}
enterAnimation(baseEl: HTMLElement) {
return this.animationCtrl
.create()
.addElement(baseEl.querySelector('.modal-wrapper')!)
.keyframes([
{ offset: 0, opacity: '0', transform: 'translate
Y(100%)' },
{ offset: 1, opacity: '1', transform: 'translateY(0)' },
])
.duration(500)
.easing('ease-out');
}
leaveAnimation(baseEl: HTMLElement) {
return this.animationCtrl
.create()
.addElement(baseEl.querySelector('.modal-wrapper')!)
.keyframes([
{ offset: 0, opacity: '1', transform: 'translateY(0)' },
{ offset: 1, opacity: '0', transform: 'translateY(100%)' },
])
.duration(500)
.easing('ease-in');
}
}
¡Y eso es todo! Ahora tienes un modal con animaciones personalizadas de entrada y salida, junto con opciones de personalización para el fondo y el cierre mediante el fondo táctil.