opacity
Color
Controla la opacidad de todo el elemento: contenido, padding, borde e hijos incluidos. A diferencia del canal alfa de rgba(), opacity afecta al elemento completo y crea un nuevo contexto de apilamiento.
opacity es la propiedad CSS que controla la opacidad de todo el elemento: el texto, el fondo, los bordes, las imágenes y todos sus elementos hijos quedan igual de transparentes al mismo tiempo. Acepta un valor entre 0 (completamente transparente, invisible) y 1 (completamente opaco, el default). No existe opacity: 50% — el valor siempre es un número decimal entre 0 y 1.
La distinción más importante de opacity es que actúa sobre el elemento como unidad: afecta al elemento pintado completo, incluidos todos sus descendientes. No hay forma de “rescatar” a un hijo de un padre con opacity baja — si el padre tiene opacity: 0.4, todos los hijos también quedarán al 40%, sin importar qué valor de opacity tengan ellos mismos. Esto la diferencia radicalmente del canal alfa de rgba() o hsla(), que solo afectan a ese color de esa propiedad específica, dejando intacto el resto del elemento.
opacity también tiene un efecto secundario importante en el modelo de renderizado: cualquier elemento con un valor de opacity menor que 1 crea un nuevo contexto de apilamiento (stacking context), igual que position: relative con z-index o transform. Esto significa que los hijos del elemento no pueden salirse visualmente del padre en el eje Z — y puede producir sorpresas cuando z-index de elementos hijos no funciona como se espera.
Cómo funciona
El navegador renderiza el elemento y todos sus hijos de forma normal, y luego aplica la opacidad al “snapshot” resultante como si fuera una capa completa. Por eso no es posible que un hijo sea más opaco que su padre:
.padre { opacity: 0.5; }
.hijo { opacity: 1; } /* el hijo sigue viendo el 50% del padre — máximo opaco */
El hijo pintado como opaco, pero ese pintado se aplica sobre la capa semitransparente del padre. El valor de opacity de los hijos se multiplica por el del padre: un hijo con opacity: 0.8 dentro de un padre con opacity: 0.5 resulta en una opacidad efectiva de 0.4.
.deshabilitado {
opacity: 0.4; /* todo el elemento al 40% */
pointer-events: none; /* opcional: deshabilitar interacción */
cursor: not-allowed;
}
Sintaxis
selector {
opacity: <número>; /* 0 a 1, inclusive */
}
Valores
1 (valor por defecto)
El elemento es completamente opaco. No hay efecto visible. Es el comportamiento normal de todos los elementos que no declaran opacity.
0
El elemento es completamente transparente. No se ve, pero sigue ocupando espacio en el layout y sigue siendo interactivo a menos que se agregue pointer-events: none. Es diferente de visibility: hidden (que también oculta pero mantiene el espacio) y de display: none (que quita el elemento del layout completamente).
.oculto-accesible {
opacity: 0;
pointer-events: none;
/* el elemento sigue en el DOM y puede ser leído por lectores de pantalla */
}
Valores entre 0 y 1
Cualquier decimal entre 0 y 1 produce una opacidad parcial. Los valores más comunes en la práctica:
| Valor | Efecto |
|---|---|
0.1 | Casi invisible — solo se intuye |
0.35 | Elemento claramente atenuado — señal de “deshabilitado” |
0.5 | Semitransparente — útil para overlays |
0.75 | Levemente transparente |
0.9 | Casi opaco — sutil |
.overlay {
background-color: #000;
opacity: 0.5; /* overlay oscuro semitransparente */
}
.tarjeta-disabled {
opacity: 0.35; /* señal visual de estado deshabilitado */
pointer-events: none;
}
.badge-fantasma {
opacity: 0.1; /* barely there */
}
La diferencia clave: opacity vs canal alfa de rgba()
Esta es la distinción más importante de la propiedad y la que más frecuentemente causa confusión:
Canal alfa de rgba() | opacity | |
|---|---|---|
| Afecta a | Solo ese color de esa propiedad | Todo el elemento (fondo, texto, borde, hijos) |
| Los hijos | No se ven afectados | Sí — quedan igual de transparentes |
| Uso típico | Fondo semitransparente con texto opaco | Elemento entero desvanecido |
| Stacking context | No lo crea | Sí lo crea (si es < 1) |
/* rgba() — solo el fondo es semitransparente; el texto queda OPACO */
.banner {
background-color: rgba(37, 99, 235, 0.15); /* fondo azul tenue */
color: rgb(30, 30, 30); /* texto completamente opaco */
}
/* opacity — TODO el elemento queda semitransparente: fondo Y texto */
.tarjeta-disabled {
opacity: 0.35; /* el fondo Y el texto del elemento se atenúan */
}
rgba() — solo el fondo
Texto opaco sobre fondo tenue
opacity — todo el elemento
Texto Y fondo atenuados
Ejemplo realista
Tarjeta de producto en estado “sin stock” y overlay de modal:
/* Estado deshabilitado / sin stock */
.tarjeta-sin-stock {
opacity: 0.4;
pointer-events: none;
cursor: not-allowed;
}
/* Overlay oscuro detrás de un modal */
.modal-overlay {
position: fixed;
inset: 0;
background-color: #000;
opacity: 0.5;
}
Cuándo usarlo
Usá opacity cuando querés atenuar visualmente el elemento completo — ideal para estados deshabilitados, loading, overlays y animaciones de aparecer/desaparecer. Usá el canal alfa de rgba() cuando solo querés que una propiedad específica (típicamente el fondo) sea semitransparente mientras el resto del elemento permanece opaco.
Para transiciones de aparición, opacity combinada con transition es la técnica estándar:
.tooltip {
opacity: 0;
transition: opacity 200ms ease;
}
.tooltip.visible {
opacity: 1;
}
Notas, gotchas e interacción
opacitycrea un stacking context si su valor es menor que 1. Esto puede romper elz-indexde elementos hijos que intentan posicionarse encima de otros elementos fuera del padre. El gotcha: un hijo conz-index: 9999no puede salirse del stacking context del padre.opacity: 0no equivale adisplay: none. Un elemento invisible conopacity: 0sigue en el flujo del layout (ocupa espacio), sigue siendo interactivo (a menos que se usepointer-events: none) y puede ser leído por lectores de pantalla.- No se puede aplicar
opacitysolo al texto de un elemento sin afectar el fondo — eso requiere usarcolorcon un valorrgba()semitransparente en lugar deopacity. - Animaciones y rendimiento. Las animaciones de
opacityson de las más eficientes en el navegador (junto contransform): se ejecutan en la GPU sin necesidad de recalcular layout ni repintar. Son el método preferido para animaciones de aparición/desaparición. - Herencia:
opacityno hereda en el sentido de CSS (no aparece en el valor computado de los hijos). Lo que ocurre es que el efecto visual se aplica al elemento renderizado completo, incluyendo hijos — pero un hijo no puede declararopacity: 1para “cancelar” el padre.
Vigente / legacy
opacity está completamente vigente desde CSS3. Existía como filtro propietario en IE antiguo (filter: alpha(opacity=50)), pero eso es legacy absoluto. En cualquier proyecto moderno, opacity funciona con soporte universal.