Otros Tokens
Tokens adicionales para control de apilamiento y otros valores especializados del sistema de diseño.
Z-Index (Apilamiento)
Los tokens de z-index controlan el orden de apilamiento de elementos en el eje Z, determinando qué elementos aparecen sobre otros.
Escala de Z-Index
| Token | Valor | Uso |
|---|---|---|
z-index-dropdown | 1000 | Menús desplegables |
z-index-sticky | 1020 | Elementos sticky (navegación fija) |
z-index-fixed | 1030 | Elementos con position: fixed |
z-index-modal-backdrop | 1040 | Fondos oscuros de modales |
z-index-modal | 1050 | Modales y diálogos |
z-index-popover | 1060 | Popovers sobre modales |
z-index-tooltip | 1070 | Tooltips (siempre visible) |
z-index-snackbar | 2000 | Notificaciones toast/snackbar |
Jerarquía de Apilamiento
Los valores están espaciados en incrementos de 10-20 para permitir valores intermedios si es necesario. Los snackbars tienen el valor más alto (2000) para asegurar que siempre sean visibles.
Uso
- CSS/HTML
- Angular
- Flutter
Variables CSS
:root {
/* Z-Index Tokens */
--z-index-dropdown: 1000;
--z-index-sticky: 1020;
--z-index-fixed: 1030;
--z-index-modal-backdrop: 1040;
--z-index-modal: 1050;
--z-index-popover: 1060;
--z-index-tooltip: 1070;
--z-index-snackbar: 2000;
}
Ejemplos de uso
/* Menú desplegable */
.dropdown-menu {
position: absolute;
z-index: var(--z-index-dropdown);
background: white;
box-shadow: var(--shadow-md);
}
/* Navegación sticky */
.navbar-sticky {
position: sticky;
top: 0;
z-index: var(--z-index-sticky);
background: white;
}
/* Backdrop de modal */
.modal-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
z-index: var(--z-index-modal-backdrop);
}
/* Modal */
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: var(--z-index-modal);
background: white;
box-shadow: var(--shadow-lg);
}
/* Tooltip */
.tooltip {
position: absolute;
z-index: var(--z-index-tooltip);
background: var(--color-gray-600);
color: white;
padding: var(--spacing-xs) var(--spacing-sm);
border-radius: var(--border-radius-md);
}
/* Snackbar/Toast */
.snackbar {
position: fixed;
bottom: var(--spacing-lg);
left: 50%;
transform: translateX(-50%);
z-index: var(--z-index-snackbar);
background: var(--color-gray-600);
color: white;
}
/* Popover sobre modal */
.popover {
position: absolute;
z-index: var(--z-index-popover);
background: white;
box-shadow: var(--shadow-md);
}
Variables CSS
:root {
/* Z-Index Tokens */
--z-index-dropdown: 1000;
--z-index-sticky: 1020;
--z-index-fixed: 1030;
--z-index-modal-backdrop: 1040;
--z-index-modal: 1050;
--z-index-popover: 1060;
--z-index-tooltip: 1070;
--z-index-snackbar: 2000;
}
Ejemplos de uso
// En estilos de componente
@Component({
selector: 'app-modal',
styles: [`
.backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
z-index: var(--z-index-modal-backdrop);
}
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: var(--z-index-modal);
}
`]
})
export class ModalComponent {}
// En archivos SCSS usando tokens de WebFoundation
@use '@tiendana/web-foundation' as tdn;
.dropdown-menu {
position: absolute;
z-index: tdn.$z-index-dropdown;
background: white;
box-shadow: tdn.$shadow-md;
}
.navbar-sticky {
position: sticky;
top: 0;
z-index: tdn.$z-index-sticky;
background: white;
}
.tooltip {
position: absolute;
z-index: tdn.$z-index-tooltip;
background: tdn.$color-gray-600;
color: white;
}
.snackbar {
position: fixed;
bottom: tdn.$spacing-lg;
z-index: tdn.$z-index-snackbar;
}
// O usar CSS variables
.other-component {
z-index: var(--z-index-modal);
}
Definir Z-Index
class TiendanaZIndex {
// Z-Index no es un concepto directo en Flutter
// Usa el orden de widgets en el stack
// Valores de referencia para documentación:
static const int dropdown = 1000;
static const int sticky = 1020;
static const int fixed = 1030;
static const int modalBackdrop = 1040;
static const int modal = 1050;
static const int popover = 1060;
static const int tooltip = 1070;
static const int snackbar = 2000;
}
Ejemplos de uso
// En Flutter, el orden de apilamiento se controla
// con el orden de los widgets en Stack
// Modal con backdrop
Stack(
children: [
// Contenido principal (nivel más bajo)
MainContent(),
// Backdrop (nivel medio)
if (showModal)
GestureDetector(
onTap: closeModal,
child: Container(
color: Colors.black.withOpacity(0.5),
),
),
// Modal (nivel más alto en este stack)
if (showModal)
Center(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: TiendanaBorders.radiusXl2,
boxShadow: TiendanaShadows.shadowLg,
),
child: ModalContent(),
),
),
],
)
// Tooltip con Overlay
OverlayEntry createTooltip() {
return OverlayEntry(
builder: (context) => Positioned(
top: position.dy,
left: position.dx,
child: Material(
color: Colors.transparent,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: TiendanaSpacing.sm,
vertical: TiendanaSpacing.xs,
),
decoration: BoxDecoration(
color: TiendanaColors.gray600,
borderRadius: TiendanaBorders.radiusMd,
),
child: Text(
'Tooltip',
style: TextStyle(color: Colors.white),
),
),
),
),
);
}
// SnackBar (usa Scaffold.of(context).showSnackBar)
// Flutter maneja el z-index automáticamente
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Notificación'),
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.all(TiendanaSpacing.lg),
),
);
Z-Index en Flutter
Flutter no usa z-index directamente. El orden de apilamiento se controla por:
- Orden en Stack: El último widget aparece arriba
- Overlay: Para elementos globales como tooltips
- Navigator: Para rutas y diálogos
- Scaffold: Para SnackBars y BottomSheets
Jerarquía de Apilamiento
┌──────────────────────────────────────┐
│ Snackbar/Toast (2000) │ Siempre visible
├──────────────────────────────────────┤
│ Tooltip (1070) │
│ Popover (1060) │
│ Modal (1050) │
│ Backdrop de modal (1040) │
│ Fixed Elements (1030) │
│ Sticky Elements (1020) │
│ Dropdown (1000) │
├──────────────────────────────────────┤
│ Contenido Normal (auto/0) │ Contenido base
└──────────────────────────────────────┘
Patrones Comunes
Modal con Backdrop
/* Backdrop detrás del modal */
.modal-backdrop {
z-index: var(--z-index-modal-backdrop); /* 1040 */
}
/* Modal sobre el backdrop */
.modal {
z-index: var(--z-index-modal); /* 1050 */
}
Popover sobre Modal
/* Cuando necesitas un popover dentro de un modal */
.modal {
z-index: var(--z-index-modal); /* 1050 */
}
.popover-in-modal {
z-index: var(--z-index-popover); /* 1060 - Mayor que modal */
}
Navegación Sticky
/* Navbar que se queda fija al hacer scroll */
.navbar {
position: sticky;
top: 0;
z-index: var(--z-index-sticky); /* 1020 */
}
Guías de Uso
✅ Mejores Prácticas
- Usa tokens de z-index en lugar de valores arbitrarios
- Respeta la jerarquía establecida
- Usa valores intermedios solo cuando sea absolutamente necesario
- Documenta por qué necesitas un z-index personalizado
- Evita z-index superiores a 2000
❌ Evita
- Valores hardcodeados como
z-index: 9999 - "Z-index wars" (incrementar valores sin control)
- Usar z-index sin position (relative, absolute, fixed)
- Z-index en elementos que no lo necesitan
- Valores negativos (excepto casos muy específicos)
Debugging de Z-Index
Si un elemento no aparece sobre otro:
- Verifica position: El elemento debe tener
position: relative,absolute,fixed, osticky - Verifica el stacking context: Elementos con
transform,opacity < 1, etc. crean nuevos contextos - Verifica la jerarquía: Asegura que estés usando el token correcto
- Usa DevTools: Inspecciona el z-index computado en el navegador
Accesibilidad
- Los modales deben tener
aria-modal="true" - Usa
role="dialog"para diálogos - Asegura que el focus trap funcione en modales
- Los tooltips deben tener
role="tooltip" - Snackbars deben usar
role="status"orole="alert"