Elementos emergentes en HTML de forma nativa

HTML5 incorpora etiquetas que permiten definir elementos con comportamiento dinámico más allá de los elementos de formulario, y sin necesidad de recurrir prácticamente a JavaScript para su uso.

Primer caso. Etiqueta details

Esta etiqueta muestra un elemento desplegable inicialmente cerrado, donde solo se ve el título del elemento junto a una flecha al lado. Al clicar sobre el título el elemento se despliega mostrando su contenido.

Dentro de la etiqueta details podemos anidar todo el HTML que necesitemos para configurar su contenido.

Si queremos personalizar el título a mostrar del elemento usaremos una etiqueta summary. Aunque la especificación dice que esta etiqueta debe ser la primera etiqueta anidada dentro de details, lo cierto es que aunque esté en otro punto de ese contenedor se mosrtará correctamente.

En caso de que no definamos esa etiqueta el navegador pone un contenido por defecto como título. Normalmente la palabra "Detalles"

Ejemplo

Este código:


            <details>
                <summary>Consultar Ficha</summary>
                <div>
                    <h2>Datos del alumno</h2>
                    <img src="gatito.jpg" alt="Foto del alumno">
                    <p>Nombre</p>
                </div>
            </details>
            

Nos devuelve

Consultar Ficha

Datos del alumno

Foto del alumno

Nombre

Atributo open

Este atributo de la etiqueta HTML permite definir que el comportamiento inicial del elemento sea expandido en lugar de cerrado. Se define así:

<details open>...</details>

Esta propiedad es Booleana, no necesita tener un valor, sólo es necesario que esté definida en la etiqueta. Y para que no se muestre el elemento hay que eliminarla de la etiqueta. De hecho, definir algo así < details open="false"> es un error, porque hace justo lo contrario de lo esperado. Al aparecer la palabra open en la etiqueta, ya fuerza a que el elemento sea visible, ignorando el valor "false".

Selector CSS open

Mediante este selector podemos aplicar un formato diferente al elemento cuando está abierto. Realmente es el selector por atributo de CSS, solo que aquí no se especifica ningún valor, es suficiente con nombrarlo. Se declara así:


            details[open] {
                ...formato del elemento abierto...
            }
        
     

Este es el CSS usado con el ejemplo anterior:


        details {
            background-color: darkgreen;
            width: 450px;
            border: 3px solid darkgreen;
            font-size: 1.2rem;
            padding: 0.5rem;
            transition: all 1s;
        }
        details[open] {
            background-color: lightblue;
            color: white;
            border-radius: 1rem;
        }
        details[open] summary {
            color: goldenrod;
        }
        

Pseudoelemento ::marker

El icono que aparece a la izquierda del título para desplegar el cuadro es un elemento de tipo lista de HTML. Eso significa que podemos acceder a él mediante el pseudoselector ::marker, y que responderá a las propiedades de lista de CSS, como list-style, por ejemplo.

Pulsa el siguiente botón para modificar el formato del icono del elemento details del ejemplo anterior. Al pulsarlo convertimos el triángulo en un cuadrado de color rojo. Si lo vuelves a pulsar retoma su formato inicial.

Segundo caso. Etiqueta dialog

El elemento dialog permite mostrar un cuadro emergente al estilo de los elementos del objeto window que podemos usar mediante javaScript como los cuadros de mensaje alert, y los cuadros de confirmación confirm o los de introducción de datos prompt.

Esta etiqueta define un elemento que inicialmente está oculto en el documento y que puede ser manejado mediante unas funciones de javaScript muy básicas.

La etiqueta dialog funciona como otro contenedor cualquiera de flujo HTML y puede contener cualquier otro fragmento de código, y de este modo construir elementos totalmente funcionales y dinámicos dentro de nuestro documento.

Este elemento tiene dos modos de presentación, la presentación en flujo del documento, y la presentación en modo modal, que hace que el resto del documento quede atenuado en un segundo plano.

La forma en que se presenta el elemento no depende del HTML del propio elemento, ni de sus atributos, es cuestión de qué función de javaScript usemos para mostrarlo en pantalla.

Por ejemplo, con este código construimos un cuadro de diálogo con texto, una imagen y un botón:


            <dialog id="emergente">
                <h2>Otro ejemplo de ficha del alumno</h2>
                <p>Con un texto</p>
                <img src="gatito.jpg" alt="">
                <em>Y una imagen</em>
                <button id="btn_cerrar">Cerrar</button>
            </dialog>
        

Otro ejemplo de ficha del alumno

Con un texto

Y una imagen

Para mostrarlo como una ventana emergente pero no modal, usamos la función show(), en este caso asignada al botón que tenemos a continuación:

Su código es este:


        document.getElementById('btn_emer').onclick = function (){
            document.getElementById('emergente').show();
        }
        

Y en el botón de la propia ventana añadimos el código para cerrar el cuadro, de esta forma:


        document.getElementById('btn_cerrar').onclick = function (){
            document.getElementById('emergente').close();
        }
        

Y si queremos que la ventana se abra de forma modal, sin que podamos trabajar con el resto del documento, esta es la función que aplicamos sobre el botón siguiente


        document.getElementById('btn_modal').onclick = function (){
            document.getElementById('emergente').showModal();
        }
       

Atributo open

De igual modo que ocurre con la etiqueta details podemos hacer que el cuadro emergente esté inicialmente abierto en el documento (se muestre), aplicando el atributo open sobre él. Diríamos algo así: < dialog open>...html que aparece visible...</dialog>

Pseudoelemento ::backdrop

Cuando la ventana se abre en modo modal (no en el normal) tenemos acceso a un pseudoelemento que nos permite configurar el fondo de detrás de la ventana de diálogo para atenuar el contenido que queda detrás.

Este es el CSS aplicado sobre el elemento dialog


        dialog {
            width: 40%;
            background-color: lightgray;
            border-radius: 1rem;
            left: 30%;
        }
        dialog::backdrop {
            background-color: rgba(255,255,255,0.9);
         }
       

Uso de cuadros de diálogo con formularios en su interior

Un caso especial del uso del elemento dialog es cuando colocamos en su interior un elemento form. En ese caso podemos hacer que el elemento dialog recoja los datos que le envía el formulario desde cualquiera de los botones que contenga dicho formulario.

Para esto, en primer lugar, tenemos que configurar el formulario para que mande los datos al cuadro de diálogo. Esto lo conseguimos configurando el atributo method del formulario con el valor dialog.

Ese valor le indica al formulario que cierre el cuadro de diálogo y al mismo tiempo le pase un dato con el valor del atributo value del botón sobre el que hemos pulsado en el formulario. Al dato enviado se puede acceder desde el cuadro de diálogo mendiante la propiedad retunValue.

Aunque no podemos leer directamente todos los values de los input y select del formulario para pasarlos directamente al cuadro, tenenmos que hacer un procedimiento con javaScript para acceder a esos datos y añadirlos al botón de envío antes de pasarlos al cuadro de diálogo.

Ejemplo

Este es el HTML:


            <dialog id="form_dialogo">
                <form method="dialog">
                    <p>
                        <label for="sel_valor">Selecciona un elemento</label>
                        <select name="sel_valor" id="sel_valor">
                            <option value="1">1</option>
                            <option value="2">2</option>
                            <option value="3">3</option>
                            <option value="4">4</option>
                            <option value="5">5</option>
                        </select>
                    </p>
                    <p>
                        <label for="intro_txt">Tu nombre:</label>
                        <input type="text" name="intro_txt" id="intro_txt">
                    </p>
                    <button value="cancelar">Cancelar</button>
                    <button id="btn_enviar">Enviar</button>
                    <button value="nada seleccionado ">Nada</button>
                </form>
            </dialog>
        

Y este es el código javaScript para hacerlo funcionar


            let seleccion = document.getElementById('sel_valor');
            let intro = document.getElementById('intro_txt');
            let enviar = document.getElementById('btn_enviar');
            intro.onchange = function () {
            enviar.value =intro.value + ' - ' + seleccion.value;
            }
            document.getElementById('form_dialogo').onclose = function () {
            alert(document.getElementById('form_dialogo').returnValue)
            }