Enlaces vacíos y semánticos

6/abr/2009 8

Si desayunas jQuery, almuerzas Mootools y cenas Spry entonces seguro te gusta manipular eventos utilizando elementos del DOM ya generados. Deben saber que la etiqueta correcta para click (y doubleclick) es <a> y solamente <a>; todas las demás tienen otros muchos usos pero la única que semánticamente está habilitada para desencadenar una acción mediante un click es… ¡<a>!

Bien eso era lo primero que quería dejar claro; he visto demasiados <li>, <h1>, incluso <p> clickeables. Ahora, a lo que va este artículo es cómo la semántica se está dejando atrás por la comodidad de escribir eventos mediante JS. Me culpo también por caer en lo mismo, pero me interesa ahora mostrarles la mejor solución que he encontrado al respecto.

Pongámonos en un caso de ejemplo. Supongamos que se agrega una función para ejecutar un slideToggle a un enlace; por lo que he visto generalmente esto se hace de 2 maneras:

<a href="#" id="ejecuta_toggle">Ejecutar slideToggle</a>

Cumples con tener un href funcional (no vacío) pero puede hacer que al hacer click la página haga scroll hasta el inicio dado que tienes un ancla vacío en el href y quizás tengas que dar un return false al final de la función del slideToggle, ó

<a href="javascript:void(0)" id="ejecuta_toggle">Ejecutar slideToggle</a>

Que hace que el browser no ejecute el enlace y no se salga de la misma página.

Enfin, son 2 métodos similares y que cumplen con el objetivo primario de ejecutar algun comportamiento mediante Javascript a través de un hyperlink. Pero nuevamente mi pregunta: ¿Qué sucede con la semántica? ¿Cómo le digo al buscador, indexador, robot que ese <a> no es un enlace realmente? ¿Que lo estoy disfrazando para cumplir con mis objetivos?

Complicada pregunta y simple respuesta. Con esta inquitud espero que puedan ir más allá en sus desarrollos; recuerden que un simple click puede desencadenar muchos más eventos que los que tienen planificado para él, eventos que benefician a sus usuarios mediante indexaciones más precisas.

La solución

Entreguen una ancla semántica al hyperlink, pero una ancla sobre sí mismo. Ejemplifico con lo mismo que he estado utilizando:

<a href="#ejecuta_toggle" name="ejecuta_toggle" id="ejecuta_toggle">Ejecutar slideToggle</a>

Con este método conservan la semántica indicando a través del atributo name qué hará ese mismo enlace y al mismo tiempo evitan el movimiento de scroll de la página.

Comentarios

  1. Pablo [#]

    La solución es un avance pero no creo que sea la definitiva.
    Si el link lo tienes a mitad de pagina, hará scroll hasta posicionarlo arriba de todo…

  2. OMA2k [#]

    En realidad en la mayoría de páginas no se usa ninguno de esos dos códigos tan “bonitos” que pones, sino el típico y anticuado onclick. Es decir:

    <a href=”javascript:void(0)” onclick=”funcionEjecutaToggle()”>Ejecutar slideToggle</a>

    O bien, el no menos anticuado e “intrusivo” método de utilizar “javascript:” para llamar a la función así:

    <a href=”javascript:funcionEjecutaToggle()”>Ejecutar slideToggle</a>

    Lamentablemente, muchos desconocen otro método que no sea con onclick dentro de una etiqueta o con href=”javascript:”, pues lo poco que saben de JS lo aprendieron “con alfileres” y mediante algún cutre-tutorial de esos que pululan por la red desde hace muchos años.

    En cualquier caso, los enlaces “javascript:” creo que no se deberían usar en ningún caso (ni siquiera de la forma que comentas, sin onclick en la etiqueta y definiendo el evento fuera del HTML), pues dan problemas de accesibilidad (sin JavaScript el enlace es inútil; no va a ningún lado) y usabilidad (por ejemplo, al pulsar con la rueda en un enlace de ese tipo para abrir en una pestaña aparte, provoca que se abra una pestaña en blanco, en vez del contenido al que se dirige el enlace).

    Y la alternativa de usar un ancla, ya sea genérica (href=”#”) o con nombre (href=”#ancla”) tampoco es muy buena, por lo mismo: sin JavaScript, ese enlace no lleva a ningún lado (y si quieres abrir una pestaña desde ese enlace, se abrirá la misma página en la nueva pestaña en vez de lo que se supone que se quería mostrar).

    ¿Entonces qué falla aquí en el caso concreto del SlideToggle? Los enlaces que abren y cierran el árbol no son realmente enlaces (no van a ningún lado) sino que son acciones que añaden interactividad a la página local, sin cambiar de página en ningún momento, por tanto en mi opinión no deberían ser <a>.

    Creo que NO se debe utilizar <a> para CUALQUIER elemento pulsable, como dices. Si se quiere desarrollar HTML “semántico”, los <a> se deberían usar sólo para lo que son: enlaces a otras páginas, ya sea de nuestro sitio o de otro sitio externo (se pueden añadir eventos JS a los <a> para que realicen otras tareas alternativas si se desea, como por ejemplo abrir una página dentro de un “ThickBox”, pero el atributo href debería ser siempre una página real, para que siga funcionando en caso de que JS esté deshabilitado o se quiera abrir una pestaña en vez de hacer un clic con el botón izquierdo).

    ¿Qué pasa si realmente no tiene sentido enlazar con otra página porque sólo queremos llamar a un evento JS? Entonces lo que ocurre es que estamos utilizando la etiqueta incorrecta. Es decir, que <a> no es lo que necesitamos aquí.

    Para elementos pulsables que sólo desencadenen acciones de forma local sin cargar otra página, puesto que no son enlaces reales, creo que en vez de <a> lo suyo es usar otro elemento HTML pensado para interactividad como <input type=”button”> o <button>. En mi caso, prefiero este último. Es un elemento muy poco usado pero bastante flexible (admite etiquetas HTML dentro del botón, al contrario que <input>), es 100% estándar, y se puede estilar con CSS como queramos.

    <button id=”toggle1″ type=”button”>Ejecutar slideToggle</button>

    Una vez colocado y estilado el botón, a partir del id le añadiríamos el evento desde JS. El type=”button” es opcional, pero lo añado ya que por defecto el tipo de los elementos <button> es “submit”. Añadiendo type=”button” evito que se recargue la página al pulsar el botón con JS deshabilitado.

    Creo que este código sería bastante más limpio y semántico que crear “falsos enlaces”. Puesto que aquí no queremos cambiar de página sino símplemente interactuar con un elemento, no tiene sentido usar <a href=””>

    Y en cuanto a la accesibilidad, no hay problema, puesto que con JavaScript deshabilitado el árbol está todo visible por defecto y los enlaces de apertura de árboles ya no hacen falta. Pulsar esos botones simplemente no hará nada, igual que si fuese un href=”#” pero con la diferencia de que es más “semántico” y la ventaja de que no se abrirán accidentalmente pestañas con la misma página.

    Bueno, ya me diréis qué os parece lo que comento. Quizá haya alguna forma aún mejor de hacerlo, pero creo que al menos es mejor que usar enlaces para lo que no fueron pensados.

    ¡Saludos!
    OMA2k

  3. Jorge Epuñan [#]

    Excelente aporte OMA2k, muy completo tu analisis pero discrepo en el uso de <a> solo para enlaces: recuerda que la semantica de esta etiqueta es para el uso de anclas (<a> significa anchor) asi q al estudiar para escribir este articulo tome muy en consideracion este aspecto. Estas muy en lo cierto en el uso sin javascript habilitado, lo q privilegia la accesibilidad pero a lo q me refiero son a eventos unicos y aislados, y nunca a q este sea un comportamiento habitual en un desarrollo; no deberia ser asi. Claro que esto queda a criterio de cada uno pero apelo a una conciencia global al respecto, y por lo q leo en tus palabras vas por muy buen camino.

    Felicidades, sigue con tu muy buen trabajo.

  4. OMA2k [#]

    Bueno, obviamente también se puede utilizar para enlaces internos, tipo “#ancla1″, pero siempre que sean de verdad enlaces internos, no anclas “de pega” introducidas sólo porque no nos viene bien que el href apunte a algún sitio. Es en esos casos en los que decía que creo que no se debe utilizar <a> sino otro elemento interactivo que no implique enlaces a otras páginas ni anclas en la actual. Así no nos tenemos que preocupar de que al pulsar se mueva la página hacia arriba o hacia abajo y otros problemas que comenté anteriormente.

    Las implementaciones actuales de HTML nos ofrecen pocos elementos más para interactividad, pero el de <button> creo que es bastante adecuado para esto. Podemos darle el estilo que queramos; aunque por defecto tiene aspecto de botón, podemos darle un aspecto de sólo texto si queremos.

    De todas formas, es sólo mi opinión. Todo esto es un poco subjetivo, y cada uno tendrá su opinión de cómo deben hacerse las cosas, sin que ninguna de las opiniones sea la “definitiva”.

    ¡Saludos!

  5. Oscar [#]

    onclick ftw, el atributo name ya va en retirada (sólo sigue para formularios anteriores a XForms), el atributo href de xhtml2 hará clickeables a todos los tags (si Dios quiere).

  6. jose roberto (vevni) [#]

    buen aporte, pienso q’ los dos tienen razon. tanco jorge por un lado como omak por el otro. ambos defienden sus conceptos y ambos estan correctos. utilizar elementos concebidos para otras tarea no es lo correcto, esto se debe en gran culpa a millones de manuales que existen en la red, nosotros incluso somos culpables en algunas veces, todo esto de la web semantica es relativamente nuevo. solo una cosa, recordar que hace pocos años muchos o la mayoria o todos haciamos cosas como estas, tablas, muchos divs flotantes, efectos en js que consumian recursos del procesador etc, solo no seamos tan afirmativamos y señalemos tu usas tablas, tu no usas estandares, pork en algun momento todos lo hicimos.
    pero buen post y buen comentario. saludos jorge desde cancun

Deja tu Comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

CSSLab