1. Lenguajes de marcado

HTML (HyperText Markup Language) es el lenguaje declarativo en el que están escritas las páginas web y es la piedra angular de la web. En este tema, aprenderemos sobre HTML centrándonos en las versiones más recientes del lenguaje.

Nota

HTML es un estándar vivo, mantenido por el grupo de trabajo WHATWG (Web Hypertext Application Technology Working Group). Échale un vistazo por encima a la especificación. Otra entidad, el W3C (World Wide Web Consortium), empaqueta la especificación estándar de vez en cuando y le asigna un número de versión (por ejemplo, 5.0 en 2014, 5.1 en 2016 o 5.2 en 2017). El W3C sí es el principal responsable de otros estándares de la web como CSS, que estudiaremos más adelante.

Importante

Las habilidades que deberías adquirir con este tema incluyen las siguientes:

  • Entender la diferencia entre un lenguaje de marcado con propósito semántico como HTML y un lenguaje de estilo.

  • Conocer la semántica de los elementos de HTML discutidos en clase.

  • Gestionar correctamente diferentes codificaciones de caracteres.

  • Saber crear documentos HTML válidos.

  • Usar correctamente las herramientas de desarrolladores integradas en navegadores; en particular, las Chrome DevTools.

  • Entender el papel jugado por un servidor web y cómo publicar en él contenido estático.

Hazlo tú ahora

Prepárate para este tema, leyendo en primer lugar el capítulo sobre HTML del libro «Client-Side Web Development».

1.1. Sintaxis y elementos del lenguaje HTML

HTML es el lenguaje informático básico que se usa para escribir el contenido de las páginas web (por otro lado, CSS se usa para especificar los aspectos estéticos que afectan a la presentación de las páginas y JavaScript para programar los aspectos dinámicos). En esta actividad vas a conocer los elementos fundamentales de HTML. Te basarás para ello en el código de la página web mínima que aparece a continuación, que iremos ampliando con otros elementos del lenguaje.

Atención

La forma normal de trabajar con HTML es usar tu editor de texto favorito para editar el fichero y abrir el documento resultante (con extensión .html) en un navegador. No obstante, cuando se dan los primeros pasos en el aprendizaje del lenguaje puede ser más cómodo usar entornos en línea como JSBin, que evitan tener que guardar y recargar constantemente. Hay otras herramientas similares como JSFiddle o CodePen, pero son menos recomendables desde el punto de vista educativo, ya que ocultan ciertas partes del documento HTML (por ejemplo, la cabecera) para no distraer al usuario con elementos obvios.

Una de los documentos web más sencillos que se pueden escribir es el siguiente. Comienza con la declaración de tipo de documento (doctype). Le sigue el elemento (o etiqueta) raíz html con un atributo opcional lang que indica el idioma del texto. El elemento head incluye metadatos sobre el documento: en este caso, la codificación de caracteres utilizada (hablaremos sobre ello más adelante) y el título del documento que aparecerá en la pestaña del navegador. El elemento body contiene el texto principal del documento, que en este caso es un único párrafo (elemento p) con un saludo.

Un documento HTML válido y corto.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<!doctype html>
<html lang="es">
  <head>
    <meta charset="utf-8">
    <title>Título del documento</title>
  </head>
  <body>
    <p>¡Hola, mundo!</p>
  </body>
</html>

Una de las ideas que tienes que tener más claras es que los diferentes elementos de HTML no representan propiedades estéticas de su contenido (como, por ejemplo, si un texto se muestra en negrita o si se ha de mostrar separado del texto precedente por un espacio vertical), sino únicamente propiedades semánticas (este texto enfatiza una determinada idea o este otro texto constituye un párrafo). Los aspectos estéticos se definen mediante lenguajes de estilo como CSS, que estudiaremos más adelante. Esta separación de presentación y contenido hace que el documento HTML sea independiente de la representación visual, táctil o auditiva que hagamos de él: en diferentes contextos podrían usarse diferentes hojas de estilo para el mismo documento; o un screen reader podría usar el contenido del bloque nav para permitir a una persona ciega elegir directamente qué sección del documento desea escuchar o consultar en un terminal braille; o un programa que procesa automáticamente un documento HTML (por poner un ejemplo, un buscador) no tendría que lidiar con aspectos secundarios meramente cosméticos. Además, gracias a la externalización de los estilos en un fichero aparte, es posible reutilizar los mismos estilos en múltiples documentos de HTML sin tener que duplicar su definición.

HTML tiene aproximadamente un centenar de elementos diferentes, cada uno de ellos con un propósito semántico bien definido. En este curso vamos a estudiar un subconjunto de ellos, cuyo cometido puedes consultar en MDN web docs y que se muestran en este documento más completo.

Hazlo tú ahora

La especificación estándar de HTML es un documento demasiado técnico para los propósitos de este curso y para la mayoría de los desarrolladores. La web MDN muestra esta información de forma más sencilla. En principio, acostúmbrate a usar esta web como referencia, frente a otras que pueden aparecer más arriba en los resultados de los buscadores. Usa la versión en inglés, ya que otros idiomas no siempre están actualizados. Estudia en MDN web docs todos los elementos de HTML que aparecen en este tema y asegúrate de que entiendes su propósito. Elementos adicionales, como los relacionados con los formularios, se estudiarán en otro tema. Reserva cita para tutoría si crees que no lo tienes todo claro.

El código del documento HTML más completo enlazado anteriormente es el siguiente:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
<!DOCTYPE html>

<!-- <!DOCTYPE> informa al navegador de qué versión de HTML se usó para escribir el documento; desde 
  HTML5 se usa simplemente la forma anterior -->
<!-- Definiciones de elementos tomadas de MDN web docs, developer.mozilla.org -->
<!-- El elemento <html> contiene todo el documento HTML; el atributo lang indica el idioma del contenido -->

<html lang="es">

<!-- El elemento <head> provee información general (metadatos) acerca del documento, incluyendo su 
    título y enlaces a scripts y hojas de estilos. -->
  <head>

    <!-- El elemento <meta> aporta metainformación del documento; el atributo charset de <meta> indica 
      la codificación de caracteres del documento: -->
    <meta charset="utf-8" />

    <!-- El elemento <title> indica el título del documento: -->
    <title>Blog del profesor Franz de Copenhague</title>

    <!-- El elemento <script> carga la librería MathJax que permite mostrar ecuaciones dentro de páginas
      web: -->
    <script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML'></script>
  </head>

  <!-- El elemento <body> representa el contenido de un documento HTML; solo puede haber un 
    elemento <body> en un documento: -->
  <body>

    <!-- El elemento <header> representa un grupo de datos introductorios o de navegación; puede 
      contener algunos elementos de encabezado, así como también un logo, un formulario de búsqueda, un 
      nombre de autor y otros componentes -->
    <header>

      <!-- Los elementos de encabezado implementan seis niveles de encabezado del documento; <h1> es el 
        más importante y <h6> el menos importante; un elemento de encabezado describe brevemente el 
        tema de la sección que presenta -->
      <h1>Blogs de la Universidad de la Atlántida</h1>
    </header>

    <!-- El elemento <nav> representa una sección de una página cuyo propósito es proporcionar enlaces de 
      navegación, ya sea dentro del documento actual o a otros documentos; ejemplos comunes de secciones 
      de navegación son menús, tablas de contenido e índices -->
    <nav>

      <!-- El elemento <ul>, de "unordered list", representa una lista no ordenada; cada elemento va 
        dentro del elemento <li> -->
      <ul>
        <li>Reflexiones sobre <a href="#física">física cuántica</a></li>
        <li>Reflexiones sobre <a href="#ia">inteligencia artificial</a></li>
      </ul>
    </nav>

    <!-- El elemento <main> representa el contenido principal del <body> de un documento o aplicación -->
    <main>

      <!-- El elemento <section> representa una sección genérica de un documento: -->
      <section>
        <h1>Reflexiones sobre ciencia del profesor Franz de Copenhague</h1>

        <!-- El atributo global id define un identificador único que no debe repetirse en todo el documento;
          su propósito es identificar el elemento al vincularlo en scripts u hojas de estilo -->
        <section id="física">
          <h2>Entradas sobre física cuántica ⚛</h2>
          <!-- Teclear caracteres Unicode en Linux: Ctrl+Mayús+u 269b espacio: ⚛ -->

          <!-- El elemento <p> es el apropiado para distribuir el texto en párrafos: -->
          <!-- El elemento <strong> es el apropiado para marcar con especial énfasis las partes más 
            importantes de un texto: -->
          <p>Esta sección incluye mis artículos <strong>recientes</strong> sobre física cuántica.</p>

          <!-- El elemento <article>)representa una composición auto-contenida en un documento, página, 
            una aplicación o en el sitio, que se destina a distribuir de forma independiente o reutilizable;
            podría ser un mensaje en un foro, un artículo de una revista o un periódico, una entrada de 
            blog, un comentario de un usuario, un widget interactivo o gadget, o cualquier otro elemento 
            independiente del contenido -->
          <article>

            <h3>Consecuencias del entrelazamiento cuántico (noviembre de 2016)</h3>
            <p>El entrelazamiento cuántico se define como [...]</p>

            <!-- El elemento <table> representa datos en dos o más dimensiones; cada fila se incluye dentro del
              elemento <tr> y cada celda dentro del elemento <td> (o <th> para el encabezado de la tabla): -->
            <table>
              <!-- El elemento <thead> representa el encabezado de la tabla donde suelen aparecer los nombres de
                cada campo: -->
              <thead>
                <tr>
                  <th>Encabezado 1</th>
                  <th>Encabezado 2</th>
                </tr>
              </thead>
              <!-- El elemento <tbody> encapsula una lista de filas de tabla que corresponden al cuerpo de la
                tabla: -->
              <tbody>
                <tr>
                  <td>a</td>
                  <td>b</td>
                </tr>
                <tr>
                  <td>c</td>
                  <td>d</td>
                </tr>
              </tbody>
              <!-- El elemento <tfoot> representa el pie de la tabla -->
              <tfoot>
                <tr>
                  <td>Pie 1</td>
                  <td>Pie 2</td>
                </tr>
              </tfoot>
            </table>
          </article>
        </section>
 
        <section id="ia">
          <h2>Entradas sobre inteligencia artificial ♟</h2>
          <p>Esta sección incluye mis artículos recientes sobre inteligencia artificial.</p>
          <article>
            <h3>Hacia una inteligencia artificial de propósito general (septiembre de 2017)</h3>
            <h4>Introducción</h4>
            <p>Los recientes avances [...] En una charla reciente, Andrew Ng señalaba que:</p>
 
            <!-- El elemento <blockquote> indica que el texto rodeado por el elemento es una cita; su atributo
              cite indica la fuente de la cita: -->
            <!-- El atributo lang se define al principio para todo el documento, pero aquí se indica para la cita;
              el valor del atributo ha de coincidir con alguno de los códigos de dos letras ISO 639-1: 
              https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes --> 
            <!-- &ldquo; es una entidad que permite introducir el signo de apertura de comillas en documentos
              con codificaciones de caracteres que no incluyen dicho simbolo: -->
            <blockquote cite="http://time.com/4631730/andrew-ng-artificial-intelligence-2017/" lang="en">
              &ldquo;We're making this analogy that artificial inteligence is the new electricity. Electricity
              transformed industries: agriculture, transportation, communication, manufacturing. I think we are
              now in that phase where artificial inteligence technology has advanced to the point where we see
              a clear path for it to transform multiple industries.”
            </blockquote>
 
            <h4>Modelo matemático</h4>
            <p>De todo lo anterior se deduce que [...]</p>

            <!-- Las ecuaciones para la librería MathJax se encierran dentro de $$ y usan una notación propia
              de la librería (basada en el lenguaje LaTeX); atención toda esta notación es específica de la
              librería y no es HTML: -->
            $$
              [\boldsymbol{\nu}_t,\boldsymbol{\xi}_t] = \mathcal{N}\left(x_t,r^{1}_{t-1},\ldots,r^{R}_{t-1}\right)
            $$
            <p>No obstante, [...]</p>

            <!-- El elemento <pre> representa texto preformateado.; el texto en este elemento típicamente 
              se muestra en una fuente fija, no proporcional (monoespacio), exactamente como es mostrado en 
              el archivo: los espacios dentro de este elemento también son mostrados como están escritos: -->
            <!-- El elemento <code> indica que el contenido es código fuente: -->
            <pre><code>
              interface PrimaryCore {
                boolean verifyDataLine();
                void sendData(in sequence&lt;byte> data);
                void initSelfDestruct();
              }
            </code></pre>

          </article>
          <article>
            <h3>La memoria en las redes neuronales (octubre de 2016)</h3>
            <p>Tradicionalmente, las <em>redes neuronales</em> [...]</p>

            <!-- El elemento <figure> representa contenido independiente, a menudo con un título; si bien se
              relaciona con el flujo principal, su posición es independiente de este; por lo general, se trata
              de una imagen, una ilustración, un diagrama, un fragmento de código o un esquema al que se hace
              referencia en el texto principal, pero que se puede mover a otra página o a un apéndice sin que
              afecte al flujo principal: -->
            <figure>

              <!-- El elemento <img> representa una imagen en el documento; su atributo src indica el URL de la
                imagen; el atributo obligatorio alt define un texto alternativo que describe la imagen: -->
                <img src="https://images.nature.com/full/nature-assets/nature/journal/v538/n7626/images/nature20101-f1.jpg"
                alt="Esquema de una red neuronal derivable, donde se pueden observar los distintos cabezales de
                     lectura/escritura accediendo a los contenidos de la memoria.">

              <!-- El elemento <figcaption> representa un subtítulo o leyenda asociado al contenido del elemento 
                padre <figure>, pudiendo ser colocado como primer o último hijo: -->
              <figcaption>Esquema de una red neuronal derivable</figcaption>
            </figure>
          </article>
        </section>

        <!-- El elemento <aside> representa una sección de una página que consiste en contenido que está 
          indirectamente relacionado con el contenido principal del documento: -->
        <aside>
          <p>Al hilo de las reflexiones anteriores [...]</p>
        </aside>
      </section>
    </main>

    <!-- El elemento <footer> representa un pie de página para el contenido de sección más cercano o el
      elemento raíz de sección; un pie de página típicamente contiene información acerca del autor de la
      sección, datos de derechos de autor o enlaces a documentos relacionados: -->
    <footer>
      <p>© 2017, Universidad de la Atlántida</p>
    </footer>
  </body>
</html>

1.2. Representación en memoria de un documento HTML

Imaginemos que tenemos que escribir un programa que cargue en memoria un documento HTML para luego realizar algún procesamiento sobre sus elementos (por ejemplo, mostrarlo en la ventana de un navegador, extraer los datos de una tabla desde un programa en Java u obtener sus palabras para indexarlas en la base de datos de un buscador). La estructura de datos que se utiliza para ello es un árbol en el que cada nodo es un objeto que representa una parte del documento. El DOM (Document Object Model) es un conjunto estándar de métodos (una interfaz) independientes del lenguaje para interactuar con este árbol que suele, por tanto, llamarse árbol DOM. En un tema posterior estudiaremos algunos de los métodos del DOM, pero por ahora centrémonos en la forma del árbol.

La siguiente figura muestra parte de un árbol DOM:

ejemplo de árbol DOM

Árbol DOM por Birger Eriksson

Hazlo tú ahora

Dibuja el árbol DOM de los documentos HTML que hemos estudiado anteriormente y utiliza la herramienta Live DOM Viewer para comprobar si tu solución es correcta. Observa en especial el tratamiento que se hace de los espacios en blanco entre dos elementos: estos blancos tienen su propio nodo asociado lo que puede ser necesario tener en cuenta al movernos por el árbol. HTML es un lenguaje en el que, en general, las secuencias de más de un espacio en blanco, tabulador o salto de línea se tratan como si fueran un único espacio en blanco.

Consejo

Podría ser que en alguna ocasión necesites que entre dos elementos (por ejemplo, entre dos palabras) de tu página haya un espacio más grande lo habitual. Podrías en ese caso tener la tentación de usar la entidad &nbsp; (también &NonBreakingSpace;), repetida varias veces, para obtener aproximadamente este espacio extra. Comprueba una vez cómo funciona (observa la diferencia entre a &nbsp;&nbsp; b y a b) y luego no vuelvas a usarla nunca más (salvo para su verdadero propósito; sigue leyendo). Posteriormente veremos que, dentro del espíritu de separar presentación y contenido, son las hojas de estilo las que se han de encargar de definir de forma precisa la separación entre los elementos de una página. ¿Para qué existe entonces una entidad como &nbsp;? Su propósito es indicar al navegador que nunca introduzca un salto de línea en el punto en el que aparece la entidad (cosa que el navegador puede decidir hacer con cualquier otro espacio en blanco) y la interprete estrictamente como un espacio en blanco. Escribe una latitud como 40°&nbsp;41′&nbsp;21.4”&nbsp;N en un documento HTML, cambia el ancho de la ventana del navegador e intenta que se separen sus componentes en dos líneas consecutivas.

1.3. Herramientas para desarrolladores

Los navegadores suelen incorporar de serie un conjunto de herramientas para facilitar el trabajo de los desarrolladores. En particular, a estas alturas del curso ya puedes usar el panel Elements de las Chrome DevTools para inspeccionar los distintos elementos de tu página; para ello, en el navegador Google Chrome (o Chromium) sitúa el puntero del ratón encima de alguna posición de tu página web y selecciona Inspeccionar en el menú contextual; otra opción para acceder a estas herramientas es abrirlas desde el menú Más herramientas ‣ Herramientas para desarrolladores del navegador o mediante el atajo de teclado Ctrl+Shift+I o F12. Existen extensiones similares para otros navegadores, como Firebug para Mozilla Firefox.

Hazlo tú ahora

Familiarízate, siguiendo esta página de su documentación, con la pestaña Elements del entorno de las Chrome DevTools, ya que te será extremadamente útil. Práctica después las distintas posibilidades con un documento de HTML más complejo como este.

Atención

El panel Elements de las Chrome DevTools muestra una información potencialmente distinta de la opción Ver código fuente la página que aparece en el menú contextual de una página (atajo de teclado Ctrl+U), ya que esta última opción muestra siempre el código inicial descargado por el navegador y no el HTML dinámico que el navegador tiene en memoria en un determinado momento, que puede ser diferente al inicial por manipulaciones del árbol DOM, como veremos en posteriores temas.

1.4. Codificación de caracteres

Aunque hoy día la mayor parte de los sistemas operativos trabajan con la codificación de caracteres de longitud variable UTF-8, que permite representar todos los caracteres del juego de caracteres Unicode, es importante que seas capaz de saber qué codificación de caracteres se usa en tus documentos web, en los de terceros, o en tu servidor web. No tener esto en cuenta puede hacer que tu web se visualice incorrectamente en algunos navegadores. En esta actividad hablaremos de codificación de caracteres siguiendo estas diapositivas.

Hazlo tú ahora

Observa que indicar una determinada codificación en el atributo charset del elemento meta no garantiza que los caracteres del documento usen realmente dicha codificación. Usa un editor de textos que permita redactar documentos bajo diferentes codificaciones y graba tu documento HTML usando las codificaciones UTF-8 e ISO-8859-15 (Latin-1); prueba a poner el valor correcto y el incorrecto en la directiva meta y observa el resultado con los caracteres especiales al abrir el documento en el navegador. Estudia cómo se representan a nivel de bytes los caracteres en las distintas codificaciones con editores hexadecimales como HexEd.it.

1.5. Alojamiento en un servidor

Una página web normalmente se aloja en un servidor web. Si la máquina en la que lo hacemos fuera pública (nuestro ordenador personal normalmente no lo será), se podría acceder entonces al documento desde cualquier máquina conectada a internet usando convenientemente la URL del servidor. Existen muchos servidores web diferentes; algunos de los más conocidos son Apache HTTP Server (HTTPD), Internet Information Services, Apache Tomcat o Jetty. Mientras un programador desarrolla una aplicación web es habitual que lance un servidor en su máquina para ir probando sus cambios; en ese caso, el URL de acceso al servidor suele tener la forma http://localhost:8080 donde localhost es el nombre de la propia máquina como host (IP 127.0.0.1) y 8080 es un puerto libre que es necesario indicar en el URL, ya que de no hacerlo el protocolo HTTP usa por defecto el puerto 80 (y HTTPS el 443), que estará normalmente reservado para comunicarse mediante HTTP con otros ordenadores.

Hazlo tú ahora

Una de las formas más sencillas de lanzar un servidor local es usar el que Python incluye por defecto. Colócate en el directorio raíz del contenido que quieres servir y haz:

python -m SimpleHTTPServer

1.6. Validación de documentos HTML

Un aspecto básico de los documentos HTML es que estos cumplan estrictamente con las directrices de HTML, tanto a nivel sintáctico (por ejemplo, las marcas de apertura y clausura respetan el anidamiento entre elementos) como semántico (no hay dos atributos id con el mismo valor o no se usan en un elemento atributos que correspondan a otros elementos). De esta manera, se allana el camino hacia la compatibilidad entre navegadores y la usabilidad de la página web; la validación, sin embargo, no asegura que el documento se vaya a ver como el desarrollador tiene en la cabeza ni que se muestre de igual manera en todos los navegadores.

Hazlo tú ahora

Usa el validador del W3C para validar alguna de las páginas web usadas en actividades anteriores; corrige todos los errores que te indique el validador hasta conseguir validarla. Algunas de las cosas que puedes probar son:

  • dejar una etiqueta sin cerrar

  • mover el elemento meta de la cabecera al cuerpo (body) del documento

  • mover un párrafo (p) a la cabecera (head) del documento

  • eliminar el título (title) de la cabecera del documento

  • poner una imagen (img) sin el atributo alt

  • colocar un elemento de lista (li) fuera de la marca de lista (ul)

Nota

El lenguaje HTML evoluciona como cualquier otro lenguaje informático. Así, lo que hoy en día se representa como:

<meta charset=utf-8>

en XHTML o HTML4 se representaba como:

<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" >

Ten en cuenta estas diferencias cuando encuentres código de ejemplo en HTML en alguna web. Los navegadores suelen procesar correctamente la mayor parte de la última versión del estándar existente cuando son publicados, pero no debes perder de vista que un gran número de usuarios tendrás probablemente versiones antiguas del navegador. Aunque no las veremos en este curso, existen maneras de desarrollar aplicaciones web teniendo en cuenta estas versiones antiguas sin renunciar necesariamente a la versatilidad de las recientes.