soy Kseso y esto EsCSS

Múltiples labels por cada input y un input para controlarlas a todas. Slide demo

¿Quién dijo que cada input sólo puede asociarse a un label? Slider puro Css con next/prev y recuperar basado en activar el :checked con múltiples labels para cada input

Múltiples labels por cada input y un input para controlarlas a todas. Slide demo

·Por Kseso ✎ 8

Hace unas fechas compartía con todos una pequeña realización basada en el hecho de que no es necesario que el input y sus label sean adyacentes para que mantengan su funcionalidad inherente.

En concreto es el artículo "Tabs o pestañas puro css para una landing page. Inputs y sus labels separados".

En esta ocasión vamos a ir un paso más allá y romper otra de las presunciones o creencias no cuestionadas: que cada input sólo puede tener asociada un label. Craso error. En ninguna parte he encontrado que se restrinja el número de ellas por cada input. Además, si así lo haces y pasas el html por el validador verás que pasa la prueba del algodón sin problemas.

Por lo tanto, nada impide romper las dos presunciones, que sólo haya una por cada uno y que estén adyacentes, para crear una galería, slider o pestañas que hasta ahora era terreno exclusivo de js o que de hacerlo con puro Css obligaba a crear un montón de enlaces internos o anclas diferentes para ir de cada cuadro al siguiente o al anterior. Resumiendo gráficamente, lo que ves en la imagen anterior.

Aspecto final de la demo que puedes ver al final del post

La construcción y funcionamiento

Como ves en esa imagen, el cuadro seleccionado tiene un "objeto" para ir al anterior o al siguiente. Y en los restantes los cambiamos para mostrar un pulsador que lo traerá al frente.

Estos "objetos" para avanzar de un slider a otro (previo/siguiente) normalmente se le añade el destino con js o si es una realización en puro Css se crean con enlaces internos (anclas) y la pseudoclase :target.

En esta demo vamos a lograr lo mismo basándonos en la pseudoclase :checked aplicada a inputs. Y para cada input creamos varias labels con su correspondiente for='id' en cada uno de los fotogramas.

<section class='galeria'> <input type="radio" id="uno" value="1" name="tractor" checked='checked' /> <input type="radio" id="dole" value="2" name="tractor" /> <input type="radio" id="tele" value="3" name="tractor" /> <article class='card una'> <!-- Contenidos varios --> <label for='dole' class='entypo-left-bold otra'></label> <label for='tele' class='entypo-right-bold otra'></label> <label for='uno' class='entypo-arrows-ccw afin'></label> </article> <!-- Otros articles --> </section>

Se necesitan tantos inputs como cuadros vayamos a necesitar. Y en cada uno de los articles colocar tres labels. Uno del propio input que lo activa y otros dos que se corresponden con el que controla al article anterior y al siguiente.

Vuelvo a recordarte que cada input se marca o desmarca (checked / unchecked) haciendo click en el propio input o en cualquiera de sus labels. Con independencia de dónde se encuentren situado cada cual en el DOM.

El Css para controlarlos a todos

Para el correcto funcionamiento de la demo lo único que se necesita es construir los selectores apropiados. Y sí, reconozco que éstos, los selectores, son numerosos incluso para tres articles como en la demo si quieres lograr un acabado y funcionamiento aceptable.

Lo primero es ocultar los inputs y estilizar las labels según dónde se encuentren. Tenemos simultáneamente un cuadro activo y dos inactivos. En el activo un label a la izquierda y otro a la derecha para traer al frente uno u otro de los inactivos. Y en cada inactivo otro label para activarlo diréctamente. Además hay cierto efecto de las etiquetas al hacer :hover en el article que las contiene y otro más al :hover sobre ella misma.

Todo lo anterior en código Css:

La apariencia de las labels

input {visibility: hidden;} /* estilos generales de los labels */ label { background: #15BFCC; position: absolute; top: 0; bottom: 0; margin: auto 0; color: #fff; font-size: 4vw; line-height: 15vh; text-align: right; height: 15vh; width: 4vw; padding: 0 .5vw; cursor: pointer; opacity: .2; box-shadow: 0 0 1px 1px rgba(255,255,255,.5) inset; transition: .5s; } /* los labels colocados a la derecha */ .otra + .otra, #uno:checked ~ .tres .afin, #dole:checked ~ .una .afin, #tele:checked ~ .dos .afin { right: 0; text-align: left; } /* los labels prev y next del cuadro activo */ #uno:checked ~ .una .otra, #dole:checked ~ .dos .otra, #tele:checked ~ .tres .otra { background: #0D757D; display: block; } /* escondo las next y prev en los cuadros inactivos y la label para activar el propio article cuando ya lo está */ #uno:checked ~ .una .afin, #dole:checked ~ .dos .afin, #tele:checked ~ .tres .afin, :not(:checked) ~ .otra {display: none;} /* resalta los label al hacer :hover sobre el article que las contien */ .card:hover label { animation: pulso 1s infinite alternate; } /* resalta el label al hacer :hover sobre él */ .card:hover label:hover { animation: none; opacity: .8; width: 10vw; }

Al código anterior, y precediéndole en el Css de la demo, están los estilos necesarios para lograr la apariencia de los 'articles' y su contenido. Entre otros, su relación de aspecto 16:9, tamaños declarados en unidades relativas al viewport, tipografías, fondos y colores.

El funcionamiento del slider

Lograda la apariencia sólo resta añadir la funcionalidad. Esto es, que se muestre un article u otro según qué input pase a ':checked' y colocar a un lado u otro los dos inactivos.

/* El input marcado y el article asociado a él */ #uno:checked ~ .una, #dole:checked ~ .dos, #tele:checked ~ .tres { animation: 2s central; animation-fill-mode: forwards; transform-origin: center center; z-index:3; } /* El input marcado y un de los articles no asociado a él */ #uno:checked ~ .dos, #dole:checked ~ .tres, #tele:checked ~ .una { animation: 1s fuera-izq; animation-fill-mode: forwards; transform-origin: center left; z-index: 2; } /* El input marcado y el otro de los articles no asociado a él */ #uno:checked ~ .tres, #dole:checked ~ .una, #tele:checked ~ .dos { animation: 1.5s fuera-dch; animation-fill-mode: forwards; transform-origin: center right; z-index: 2; }

Como ves, cada input al ser marcado fuerza una acción distinta sobre cada article que conforma el slider en base a las animaciones definidas que transcribo tras la explicación.

En primer lugar asocio, la primera regla Css de la anteriores, cada input (y por lo tanto sus labels) con un article, para que al 'checked' lo traiga al frente posicionándolo sobre (eje z) los otros dos. Y a la vez lleva a los otros dos articles uno a su derecha y otro a su izquierda.

Este baile de cada article es diferente si el input marcado es '#uno', '#dole' o '#tele'. Por eso el trío de selectores en cada una de las reglas anteriores.

El funcionamiento animado

Tras todo el trabajo anterior sólo resta animar las transiciones para cada selección. Esto, como es lógico, lo encomendamos a las @keyframes correspondientes a las 'animation' que hemos ido declarando.

/* el article seleccionado */ @keyframes central { 0% {transform: scale(.8);z-index: 1;} 80% {transform: scale(.5);z-index: 3;} 100% {transform: scale(1);z-index: 3;} } /* el article no seleccionado a la izquierda */ @keyframes fuera-izq { 0% {transform: scale(1) translatex(0%);} 70% {transform: scale(.9) translatex(-100%);} 100% {transform: scale(.9) translatex(-7%);} } /* el article no seleccionado a la derecha */ @keyframes fuera-dch { 0% {transform: scale(1) translatex(0%);} 70% {transform: scale(.9) translatex(100%);} 100% {transform: scale(.9) translatex(7%);} } /* los pulsos de los labels al :hover de su article */ @keyframes pulso { 50% {opacity: .7;} }

¡Hey! ¿Y la demo?

No. No me he olvidado de que lo que realmente quieres es ver la demo en funcionamiento. Que la mayoría de visitantes ni necesita ni quiere todo el rollo anterior sobre los códigos. Así que aquí tienes los enlaces para que disfrutes del poder del Css.

See the Pen Three Labels for each Input by Kseso (@Kseso) on CodePen.

Ver demo a fullDescargar códigos

Si optas por usar los códigos recuerda que quizás necesites añadir prefijos privativos a ciertas propiedades. Ya sea diréctamente o mediante alguna herramienta como prefixfree. El archivo descargado de la demo ya lo incluye.

Artículo publicado originalmente en Noviembre de 2013.

avatar del Editor del blog

the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso