API HTML: qué son y cómo diseñar una buena

 

 

 

  • Taller de diseño conductual, con Susan y Guthrie Weinschenk
  • Smart Interface Design Patterns, 10h video + UX training

  • Índice
    1. Selector de inicio
    2. Minimizar el marcado inicial
    3. Ajustes
    4. Herencia
    5. Ajustes globales
    6. Documentación
    7. ¿Qué pasa con los componentes web?
      1. Otras lecturas

    En este artículo, Lea Verou explica qué es una API HTML, por qué son útiles y qué lecciones importantes pueden aprender los desarrolladores de ellas. Sigue leyendo para descubrir cómo diseñar uno bueno. Quizás se pregunte: "Todos los autores de HTML y CSS conocen JavaScript, ¿verdad?" Equivocado. Echa un vistazo a los resultados de la siguiente encuesta.

     

    Como desarrolladores de JavaScript, a menudo olvidamos que no todos tienen los mismos conocimientos que nosotros. Se llama la maldición del conocimiento: cuando somos expertos en algo, no podemos recordar lo confundidos que nos sentíamos cuando éramos novatos. Sobreestimamos lo que la gente encontrará fácil.

    Por lo tanto, creemos que está bien requerir una gran cantidad de JavaScript para inicializar o configurar las bibliotecas que escribimos. Mientras tanto, algunos de nuestros usuarios luchan por usarlos, copiando y pegando frenéticamente ejemplos de la documentación, modificándolos al azar hasta que funcionen.

    Quizás se pregunte: "Pero todos los autores de HTML y CSS conocen JavaScript, ¿verdad?" Equivocado. Eche un vistazo a los resultados de mi encuesta , que son los únicos datos que conozco al respecto. (Si conoce algún estudio adecuado sobre esto, ¡menciónelo en los comentarios!)

    Una de cada dos personas que escribe HTML y CSS no se siente cómoda con JavaScript . Uno de cada dos. Dejemos que eso se asimile por un momento.

    Como ejemplo, mire el siguiente código para inicializar un autocompletado de jQuery UI, tomado de su documentación :

    div label for="tags"Tags: /label input/div
    $( function() { var availableTags = [ "ActionScript", "AppleScript", "Asp", "BASIC", "C" ]; $( "#tags" ).autocomplete({ source: availableTags });} );

    Esto es fácil, incluso para personas que no conocen JavaScript, ¿verdad? Equivocado. Alguien que no sea programador tendría todo tipo de preguntas en la cabeza después de ver este ejemplo en la documentación. "¿Dónde pongo este código?" “¿Qué son estos brackets, dos puntos y brackets?” "¿Los necesito?" “¿Qué hago si mi elemento no tiene ID?” Etcétera. Incluso este pequeño fragmento de código requiere que las personas comprendan los objetos literales, matrices, variables, cadenas, cómo obtener una referencia a un elemento DOM, eventos, cuándo está listo el DOM y mucho más. Cosas que parecen triviales para los programadores pueden ser una batalla cuesta arriba para los autores de HTML sin conocimientos de JavaScript.

     

    Ahora considere el código declarativo equivalente de HTML5 :

    div label for="tags"Tags: /label input list="languages" datalist optionActionScript/option optionAppleScript/option optionAsp/option optionBASIC/option optionC/option /datalist/div

    Esto no sólo es mucho más claro para cualquiera que sepa escribir HTML, sino que es incluso más fácil para los programadores. Vemos que todo está configurado en un solo lugar, no hay necesidad de preocuparse por cuándo inicializar, cómo obtener una referencia al elemento y cómo configurar cosas en él. No es necesario saber qué función llamar para inicializar o qué argumentos acepta. Y para casos de uso más avanzados, también existe una API de JavaScript que permite que todos estos atributos y elementos se creen dinámicamente. Sigue uno de los principios de diseño de API más básicos: hace que lo simple sea fácil y lo complejo sea posible.

    Esto nos lleva a una lección importante sobre las API HTML : beneficiarían no sólo a las personas con conocimientos limitados de JavaScript. Para tareas comunes, incluso nosotros, los programadores, a menudo estamos dispuestos a sacrificar la flexibilidad de la programación por la conveniencia del marcado declarativo. Sin embargo, de alguna manera olvidamos esto cuando escribimos nuestra propia biblioteca.

    Entonces, ¿qué es una API HTML? Según Wikipedia , una API (o interfaz de programación de aplicaciones) es "un conjunto de definiciones de subrutinas, protocolos y herramientas para crear software de aplicaciones". En una API HTML, las definiciones y protocolos están en el propio HTML, y las herramientas buscan la configuración en HTML. Las API de HTML normalmente constan de ciertos patrones de clases y atributos que se pueden usar en HTML existente. Con los componentes web, incluso los nombres de elementos personalizados son un juego, y con Shadow DOM , estos pueden incluso tener una estructura interna completa que está oculta del resto del JavaScript o CSS de la página. Pero este no es un artículo sobre componentes web; Los componentes web brindan más poder y opciones a los diseñadores de API HTML; pero los principios de un buen diseño de API (HTML) son los mismos.

    Las API HTML mejoran la colaboración entre diseñadores y desarrolladores, quitan algo de trabajo de los hombros de estos últimos y permiten a los diseñadores crear maquetas de mucha mayor fidelidad. Incluir una API HTML en su biblioteca no sólo hace que la comunidad sea más inclusiva, sino que, en última instancia, también beneficia a usted, el programador.

     

    No todas las bibliotecas necesitan una API HTML. Las API HTML son principalmente útiles en bibliotecas que habilitan elementos de la interfaz de usuario como galerías, arrastrar y soltar, acordeones, pestañas, carruseles, etc. Como regla general, si alguien que no es programador no puede entender lo que hace su biblioteca, entonces su biblioteca No necesita una API HTML. Por ejemplo, las bibliotecas que simplifican o ayudan a organizar el código no necesitan una API HTML. ¿Qué tipo de API HTML tendría un marco MVC o una biblioteca auxiliar DOM?

    Hasta ahora, hemos discutido qué es una API HTML, por qué es útil y cuándo es necesaria. El resto de este artículo trata sobre cómo diseñar uno bueno.

    Selector de inicio

    Con una API de JavaScript, la inicialización está estrictamente controlada por el usuario de la biblioteca: debido a que tiene que llamar manualmente a una función o crear un objeto, controla con precisión cuándo se ejecuta y en qué. Con una API HTML, tenemos que tomar esa decisión por ellos y asegurarnos de no interponernos en el camino de los usuarios avanzados que seguirán usando JavaScript y querrán un control total.

    La forma común de resolver la tensión entre estos dos casos de uso es inicializar automáticamente solo los elementos que coincidan con un selector determinado, generalmente una clase específica. Awesommplete sigue este enfoque y solo selecciona elementos de entrada con class=“awesomplete”.

    En algunos casos, facilitar la inicialización automática es más importante que hacer explícita la suscripción. Esto es común cuando su biblioteca necesita ejecutarse en muchos elementos y cuando evitar tener que agregar manualmente una clase a cada uno de ellos es más importante que hacer explícita la suscripción. Por ejemplo, Prism resalta automáticamente cualquier codeelemento que contenga una language-xxxclase (que es lo que recomienda la especificación HTML5 para especificar el idioma de un fragmento de código ) o que esté dentro de un elemento que la contenga. Esto se debe a que podría incluirse en un blog con un montón de fragmentos de código, y tener que volver atrás y agregar una clase a cada uno de ellos sería una gran molestia.

    En los casos en los que el initselector se utiliza de forma muy liberal, una buena práctica es permitir su personalización o permitir la exclusión voluntaria de la inicialización automática. Por ejemplo, Stretchy ajusta automáticamente el tamaño de cada input y de forma predeterminada, pero selectpermite textareapersonalizar su initselector a algo más específico a través de un data-stretchy-filteratributo. Prism admite un data-manualatributo en su scriptelemento para deshabilitar completamente la inicialización automática. Una buena práctica es permitir que esta opción se configure mediante HTML o JavaScript, para adaptarse a ambos tipos de usuarios de la biblioteca.

    Minimizar el marcado inicial

    Entonces, para cada elemento initque coincida con el selector, ¿su biblioteca necesita un contenedor alrededor, tres botones dentro y dos divs adyacentes? No hay problema, pero generalos tú mismo. Este tipo de trabajo duro se adapta mejor a las máquinas, no a los humanos. No espere que todos los que usan su biblioteca también utilicen algún tipo de sistema de plantillas : muchas personas todavía crean marcas a mano y consideran que los sistemas de compilación son demasiado complicados. Hazles la vida más fácil.

     

    Esto también minimiza las condiciones de error: ¿Qué pasa si un usuario incluye la clase que espera para la inicialización pero no todo el marcado que necesita? Cuando no hay marcas adicionales que agregar, no es posible que se produzcan tales errores.

    Hay una excepción a esta regla: degradación elegante y mejora progresiva. Por ejemplo, insertar un tweet implica mucho marcado, aunque data-*sería suficiente un solo elemento con atributos para todas las opciones. Esto se hace para que el tweet sea legible incluso antes de que se cargue o ejecute JavaScript. Una buena regla general es preguntarse: ¿el marcado adicional ofrece un beneficio al usuario final incluso sin JavaScript? Si es así, entonces está bien solicitarlo. Si no, generelo con su biblioteca.

    También existe la tensión clásica entre facilidad de uso y personalización: generar todo el marcado para el usuario de la biblioteca es más fácil para ellos, pero dejar que escriban les da más flexibilidad. La flexibilidad es excelente cuando la necesitas, pero molesta cuando no la necesitas y aun así tienes que configurar todo manualmente. Para equilibrar estas dos necesidades, puede generar el marcado que necesita si aún no existe. Por ejemplo, supongamos que envuelve todos .foolos elementos con un .foo-containerelemento. Primero, verifique si el padre (o, mejor aún, cualquier ancestro, vía element.closest(".foo-container")) de su .fooelemento ya tiene la foo-containerclase y, de ser así, úsela en lugar de crear un nuevo elemento.

    Ajustes

    Normalmente, la configuración debe proporcionarse a través de data-*atributos en el elemento relevante. Si su biblioteca agrega una gran cantidad de atributos, es posible que desee asignarles un espacio de nombres para evitar colisiones con otras bibliotecas, como data-foo-*(donde foo es un prefijo de una a tres letras basado en el nombre de su biblioteca). Si es demasiado largo, puede usar foo-*, pero tenga en cuenta que esto interrumpirá la validación de HTML y podría sacar de su biblioteca a algunos de los autores de HTML más diligentes. Idealmente, debería admitir ambos, si no infla demasiado su código. Ninguna de las opciones aquí es ideal, por lo que hay una discusión en curso en WHATWG sobre si se deben legalizar dichos prefijos para atributos personalizados. Todo sobre Pinganillos

    Siga las convenciones de HTML tanto como sea posible. Por ejemplo, si utiliza un atributo para una configuración booleana, su presencia significa trueindependientemente del valor y su ausencia significa false. No esperes cosas como data-foo="true"o data-foo="false"en su lugar. Claro, ARIA hace eso, pero si ARIA saltara por un acantilado, ¿tú también lo harías?

     

    Cuando la configuración es booleana , también puedes usar clases. Normalmente, su semántica es similar a la de los atributos booleanos: la presencia de la clase significa truey la ausencia significa false. Si quieres lo contrario, puedes utilizar un no-prefijo (por ejemplo, no-line-numbers). Tenga en cuenta que los nombres de clases se utilizan más que data-*los atributos, por lo que existe una mayor posibilidad de colisión con los nombres de clases existentes del usuario. Podrías considerar anteponer tus clases con un prefijo como foo-para evitarlo. Otro peligro con los nombres de clases es que un futuro mantenedor pueda notar que no se utilizan en el CSS y eliminarlos.

    Cuando tiene un grupo de configuraciones booleanas relacionadas, usar un atributo separado por espacios puede ser mejor que usar muchos atributos o clases separados. Por ejemplo, lt;div data-permissions="read add edit delete save logoutgt;"es mejor que lt;div data-read data-add data-edit data-delete data-save data-logout"gt;y lt;divgt;probablemente causaría muchas colisiones. Luego puede dirigirse a individuos individuales a través del ~=selector de atributos. Por ejemplo, element.matches("[data-permissions~=read]")comprueba si un elemento tiene readpermiso.

    Si el tipo de configuración es una matriz u objeto , entonces puede usar un data-*atributo que se vincule a otro elemento. Por ejemplo, observe cómo HTML5 se autocompleta: debido a que el autocompletado requiere una lista de sugerencias, se utiliza un atributo para vincular a un lt;datalistgt;elemento que contiene estas sugerencias a través de su ID.

    Este es un punto en el que seguir las convenciones HTML se vuelve complicado: en HTML, el enlace a otro elemento en un atributo siempre se realiza haciendo referencia a su ID (piense en lt;label for="…"gt;). Sin embargo, esto es bastante limitante: es mucho más conveniente permitir selectores o incluso anidar si tiene sentido. Lo que elija dependerá en gran medida de su caso de uso. Solo tenga en cuenta que, si bien la coherencia es importante, la usabilidad es nuestro objetivo aquí.

    Está bien si no todas las configuraciones están disponibles a través de HTML. Las configuraciones cuyos valores son funciones pueden permanecer en JavaScript y considerarse "personalización avanzada". Considere Awesomplelete : todas las configuraciones numéricas, booleanas, de cadenas y de objetos están disponibles como atributos data-*( ,,, list) . Todas las configuraciones de funciones solo están disponibles en JavaScript ( , , , , ). Si alguien puede escribir una función de JavaScript para configurar su biblioteca, entonces puede usar la API de JavaScript.minCharsmaxItemsautoFirstfiltersortitemreplacedata

    Las expresiones regulares (regex) son un área un poco gris: normalmente, sólo los programadores conocen las expresiones regulares (¡e incluso los programadores tienen problemas con ellas!); entonces, a primera vista no parece tener ningún sentido incluir configuraciones con valores de expresiones regulares en su API HTML. Sin embargo, HTML5 sí incluyó dicha configuración ( input pattern="regex"), y creo que fue bastante exitoso, porque los no programadores pueden buscar su caso de uso en un directorio de expresiones regulares y copiar y pegar.

     

    Herencia

    Si su biblioteca de UI se va a utilizar una o dos veces en cada página, entonces la herencia no importará mucho. Sin embargo, si pudiera aplicarse a múltiples elementos, entonces sería complicado configurar los mismos ajustes en cada uno de ellos a través de clases o atributos. Recuerde que no todo el mundo utiliza un sistema de compilación , especialmente los que no son desarrolladores. En estos casos, podría resultar útil definir que las configuraciones se pueden heredar de los elementos ancestros, de modo que se puedan configurar varias instancias en masa.

    Tomemos como ejemplo Prism , una popular biblioteca de resaltado de sintaxis, que también se utiliza aquí en Smashing Magazine. El idioma de resaltado se configura mediante una clase del formulario language-xxx. Sí, esto va en contra de las pautas que analizamos en la sección anterior, pero fue una decisión consciente porque la especificación HTML5 recomienda esto para especificar el idioma de un fragmento de código. En una página con múltiples fragmentos de código (¡piense en la frecuencia con la que una publicación de blog sobre código utiliza codeelementos en línea!), especificar el lenguaje de codificación en cada codeelemento sería extremadamente tedioso. Para mitigar este dolor, Prism admite la herencia de estas clases: si un codeelemento no tiene una language-xxxclase propia, entonces se usa la de su ancestro más cercano que sí la tiene. Esto permite a los usuarios configurar el idioma de codificación globalmente (colocando la clase en los elementos bodyo html) o por sección, y anularlo solo en elementos o secciones con un idioma diferente.

    Ahora que todos los navegadores admiten las variables CSS , son un buen candidato para dichas configuraciones: se heredan de forma predeterminada y se pueden configurar en línea mediante el atributo, mediante CSS o mediante JavaScript. En tu código, los obtienes a través de . Además de la compatibilidad con el navegador, su principal desventaja es que los desarrolladores aún no están acostumbrados a ellos, pero eso está cambiando. Además, no puede monitorear los cambios en ellos a través de , como puede hacerlo con los elementos y atributos.stylegetComputedStyle(element).getPropertyValue(“–variablename”)MutationObserver

    Ajustes globales

    La mayoría de las bibliotecas de UI tienen dos grupos de configuraciones: configuraciones que personalizan cómo se comporta cada instancia del widget y configuraciones globales que personalizan cómo se comporta la biblioteca . Hasta ahora, hemos discutido principalmente lo primero, por lo que quizás se pregunte cuál es un buen lugar para estos entornos globales.

    Un candidato es el scriptelemento que incluye su biblioteca. Puede obtenerlo a través de document.currentScript, y tiene muy buena compatibilidad con el navegador . La ventaja de esto es que no queda ambiguo para qué sirven estas configuraciones, por lo que sus nombres pueden ser más cortos (por ejemplo, data-filteren lugar de data-stretchy-filter).

     

    Sin embargo, el scriptelemento no debe ser el único lugar donde puede obtener estas configuraciones, porque algunos usuarios pueden estar usando su biblioteca en un CMS que no les permite personalizar scriptelementos. También puede buscar la configuración en los elementos htmly bodyo incluso en cualquier lugar, siempre que tenga una política claramente establecida sobre qué valor gana cuando hay duplicados. (¿El primero? ¿El último? ¿Algo más?)

    Documentación

    Entonces, te has ocupado de diseñar una API declarativa agradable para tu biblioteca. ¡Bien hecho! Sin embargo, si toda su documentación está escrita como si el usuario entendiera JavaScript, pocos podrán utilizarla. Recuerdo haber visto una biblioteca interesante para alternar la visualización de elementos según la URL, a través de atributos HTML en los elementos que se van a alternar. Sin embargo, las personas a las que se dirigía no podían utilizar su agradable API HTML porque toda la documentación estaba repleta de referencias de JavaScript. El primer ejemplo comenzaba con "Esto es equivalente a location.href.match(/foo/)". ¿Qué posibilidades tiene un no programador de entender esto?

    Además, recuerda que muchas de estas personas no hablan ningún lenguaje de programación, no sólo JavaScript. No hable sobre modelos, vistas, controladores u otros conceptos de ingeniería de software en un texto que espera que lean y comprendan. Lo único que conseguirás será confundirlos y alejarlos.

    Por supuesto, también debes documentar las partes de JavaScript de tu API. Puedes hacerlo en la sección "Uso avanzado". Sin embargo, si comienza su documentación con referencias a objetos y funciones de JavaScript o conceptos de ingeniería de software, esencialmente les está diciendo a los no programadores que esta biblioteca no es para ellos, excluyendo así a una gran parte de sus usuarios potenciales. Lamentablemente, la mayor parte de la documentación de bibliotecas con API HTML sufre estos problemas, porque las API HTML a menudo se consideran un atajo para los programadores, no una forma para que los no programadores utilicen estas bibliotecas. Con suerte, esto cambiará en el futuro.

    ¿Qué pasa con los componentes web?

    En un futuro próximo, el cuarteto de especificaciones de componentes web revolucionará las API HTML. El templateelemento permitirá a los autores proporcionar guiones con marcado inerte parcial. Los elementos personalizados permitirán initun marcado mucho más elegante que se asemeja al HTML nativo. Las importaciones de HTML permitirán a los autores incluir solo un archivo, en lugar de tres hojas de estilo, cinco scripts y diez plantillas (si Mozilla se pone manos a la obra y deja de pensar que los módulos ES6 son una tecnología competidora ). Shadow DOM permitirá que su biblioteca tenga estructuras DOM complejas que estén encapsuladas adecuadamente y que no interfieran con el marcado del propio usuario.

    Sin embargo, templateaparte, la compatibilidad del navegador con los otros tres es actualmente limitada . Por lo tanto, requieren grandes rellenos, lo que los hace menos atractivos para el uso de la biblioteca. Sin embargo, es algo que debes tener en cuenta en el futuro cercano.

    Otras lecturas

    • Diseño de gráficos circulares flexibles y mantenibles con CSS y SVG
    • API de accesibilidad: una clave para la accesibilidad web
    • Llevando las bibliotecas de patrones al siguiente nivel
    • Ajuste de desplazamiento CSS alineado con el diseño de página global: un estudio de caso de control deslizante de ancho completo

    (vf, il, al, mrn)Explora más en

    • CSS
    • javascript
    • HTML
    • API





    Tal vez te puede interesar:

    1. Diseño de un cuadro de texto, íntegro
    2. Diseño y construcción de una aplicación web progresiva sin marco (Parte 3)
    3. Escribir un motor de aventuras de texto multijugador en Node.js: diseño del servidor Game Engine (Parte 2)
    4. Componentes de diseño en React

    API HTML: qué son y cómo diseñar una buena

    API HTML: qué son y cómo diseñar una buena

    Taller de diseño conductual, con Susan y Guthrie Weinschenk Smart Interface Design Patterns, 10h video + UX training Índice

    programar

    es

    https://aprendeprogramando.es/static/images/programar-api-html-que-son-y-como-disenar-una-buena-907-0.jpg

    2024-05-20

     

    API HTML: qué son y cómo diseñar una buena
    API HTML: qué son y cómo diseñar una buena

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20