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.

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.

Uno 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<!doctype html>
 2<html lang="es">
 3  <head>
 4    <meta charset="utf-8">
 5    <title>Título del documento</title>
 6  </head>
 7  <body>
 8    <p>¡Hola, mundo!</p>
 9  </body>
10</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.

Atención

Una parte importante de la sociedad tiene alguna discapacidad (visual, motora, intelectual…), ya sea congénita o adquirida (por enfermedad, accidente o edad, por ejemplo), que le puede dificultar la interacción con una página o aplicación web si esta no se desarrolla adecuadamente bajo principios de accesibilidad que atiendan a la diversidad funcional de la sociedad. El uso de HTML como lenguaje de anotación semántica de contenido es uno de los principios fundamentales para cumplir este objetivo.

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<!DOCTYPE html>
  2<!-- <!DOCTYPE> informa al navegador de qué versión de HTML se usó para escribir el documento; desde 
  3     HTML5 se usa simplemente la forma anterior -->
  4
  5<!-- Definiciones de elementos tomadas de MDN web docs, developer.mozilla.org -->
  6
  7<!-- El elemento <html> contiene todo el documento HTML; el atributo lang indica el idioma del contenido -->
  8<html lang="es">
  9
 10  <!-- El elemento <head> provee información general (metadatos) acerca del documento, incluyendo su 
 11       título y enlaces a scripts y hojas de estilo -->
 12  <head>
 13
 14    <!-- El elemento <meta> aporta metainformación del documento; el atributo charset de <meta> indica 
 15      la codificación de caracteres del documento: -->
 16    <!-- <meta> es un ejemplo de "elemento vacío", que no requiere etiqueta de inicio y de fin;
 17         en versiones anteriores del estándar, estos se elementos se representaban con una barra
 18         al final: <meta charset="utf-8"/> -->
 19    <meta charset="utf-8">
 20    <meta name="author" content="Franz de Copenhague">
 21
 22    <!-- El elemento <title> indica el título del documento: -->
 23    <title>Blog del profesor Franz de Copenhague</title>
 24
 25    <!-- El elemento <script> carga la librería de JavaScript MathJax que permite mostrar ecuaciones dentro de páginas
 26         web: -->
 27    <script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML'></script>
 28
 29    <!-- La librería de JavaScript chessboard-element permite define un componente web que permite usar
 30         el elemento personalizado chess-board (que no pertenece al estándar) en el documento -->
 31    <script type="module" src="https://unpkg.com/chessboard-element?module"></script>
 32  </head>
 33
 34  <!-- El elemento <body> representa el contenido de un documento HTML; solo puede haber un 
 35       elemento <body> en un documento: -->
 36  <body>
 37
 38    <!-- El elemento <header> representa un grupo de datos introductorios o de navegación; puede 
 39         contener algunos elementos de encabezado, así como también un logo, un formulario de búsqueda, un 
 40         nombre de autor y otros componentes -->
 41    <header>
 42
 43      <!-- Los elementos de encabezado implementan seis niveles de encabezado del documento; <h1> es el 
 44           más importante y <h6> el menos importante; un elemento de encabezado describe brevemente el 
 45           tema de la sección que presenta -->
 46      <h1>Blog del profesor Franz de Copenhague</h1>
 47    </header>
 48
 49    <!-- El elemento <nav> representa una sección de una página cuyo propósito es proporcionar enlaces de 
 50         navegación, ya sea dentro del documento actual o a otros documentos; ejemplos comunes de secciones 
 51         de navegación son menús, tablas de contenido e índices -->
 52    <nav>
 53
 54      <!-- El elemento <ul>, de "unordered list", representa una lista no ordenada; cada elemento va 
 55           dentro del elemento <li> -->
 56      <ul>
 57        <!-- El elemento <a> es la base del hipertexto; a través del atributo "href" se indica el 
 58             documento al que se saltará si se activa el enlace; en este caso, se enlaza a un
 59             elemento del documento actual etiquetado con un id -->
 60        <li>Reflexiones sobre <a href="#física">física cuántica</a></li>
 61        <li>Reflexiones sobre <a href="#ia">inteligencia artificial</a></li>
 62      </ul>
 63    </nav>
 64
 65    <!-- El elemento <main> representa el contenido principal del <body> de un documento o aplicación -->
 66    <main>
 67
 68      <!-- El elemento <section> representa una sección genérica de un documento -->
 69      <section>
 70        <h1>Reflexiones sobre ciencia del profesor Franz de Copenhague</h1>
 71
 72        <!-- El atributo global id define un identificador único que no debe repetirse en todo el documento;
 73             su propósito es identificar el elemento al vincularlo en scripts, hojas de estilo u enlaces -->
 74        <section id="física">
 75          <h2>Entradas sobre física cuántica ⚛</h2>
 76          <!-- Teclear caracteres Unicode en Linux: Ctrl+Mayús+u 269b espacio: ⚛; otros sistemas operativos 
 77               tienen sus propias combinaciones de teclas -->
 78
 79          <!-- El elemento <p> es el apropiado para distribuir el texto en párrafos -->
 80          <!-- El elemento <strong> es el apropiado para marcar con especial énfasis las partes más 
 81               importantes de un texto -->
 82          <p>Esta sección incluye mis artículos <strong>recientes</strong> sobre física cuántica.</p>
 83
 84          <!-- El elemento <article> representa una composición auto-contenida en un documento, página, 
 85               o aplicación que se podría distribuir de forma independiente o reutilizable;
 86               podría ser un mensaje en un foro, un artículo de una revista o un periódico, una entrada de 
 87               blog, un comentario de un usuario o cualquier otro elemento independiente del contenido -->
 88          <article>
 89
 90            <h3>Consecuencias del entrelazamiento cuántico</h3>
 91            <p>El entrelazamiento cuántico se define como lorem ipsum dolor sit amet, consectetur adipiscing elit, 
 92              sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud 
 93              exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.</p>
 94
 95            <!-- El elemento <table> representa datos en dos o más dimensiones; cada fila se incluye dentro del
 96                 elemento <tr> y cada celda dentro del elemento <td> (o <th> para el encabezado de la tabla) -->
 97            <table>
 98              <!-- El elemento <thead> representa el encabezado de la tabla donde suelen aparecer los nombres de
 99                   cada campo -->
100              <thead>
101                <tr>
102                  <th>Encabezado 1</th>
103                  <th>Encabezado 2</th>
104                </tr>
105              </thead>
106              <!-- El elemento <tbody> encapsula una lista de filas de tabla que corresponden al cuerpo de la
107                   tabla -->
108              <tbody>
109                <tr>
110                  <td>a</td>
111                  <td>b</td>
112                </tr>
113                <tr>
114                  <td>c</td>
115                  <td>d</td>
116                </tr>
117              </tbody>
118              <!-- El elemento <tfoot> representa el pie de la tabla -->
119              <tfoot>
120                <tr>
121                  <td>Pie 1</td>
122                  <td>Pie 2</td>
123                </tr>
124              </tfoot>
125            </table>
126          </article>
127        </section>
128 
129        <section id="ia">
130          <h2>Entradas sobre inteligencia artificial ♟</h2>
131          <p>Esta sección incluye mis artículos recientes sobre inteligencia artificial.</p>
132          <article>
133            <h3>Hacia una inteligencia artificial de propósito general</h3>
134            <h4>Introducción</h4>
135            <p>Los recientes avances lorem ipsum dolor sit amet, consectetur adipiscing elit, 
136              sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 
137              nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure 
138              reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint 
139              obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 
140              En una charla reciente, Andrew Ng señalaba que:</p>
141 
142            <!-- El elemento <blockquote> indica que el texto rodeado por el elemento es una cita; su atributo
143                 cite indica la fuente de la cita -->
144            <!-- El atributo lang se define al principio para todo el documento, pero aquí se indica para la cita;
145                 el valor del atributo ha de coincidir con alguno de los códigos de dos letras ISO 639-1: 
146                 https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes --> 
147            <!-- &ldquo; es una entidad que permite introducir el signo de apertura de comillas en documentos
148                 con codificaciones de caracteres que no incluyen dicho simbolo; existe un conjunto de entidades 
149                 definidas en el estándar como, por ejemplo, &copy; para el símbolo de copyright -->
150            <blockquote cite="http://time.com/4631730/andrew-ng-artificial-intelligence-2017/" lang="en">
151              &ldquo;We're making this analogy that artificial inteligence is the new electricity. Electricity
152              transformed industries: agriculture, transportation, communication, manufacturing. I think we are
153              now in that phase where artificial inteligence technology has advanced to the point where we see
154              a clear path for it to transform multiple industries.&rdquo;
155            </blockquote>
156 
157            <h4>Modelo matemático</h4>
158            <p>De todo lo anterior se deduce que lorem ipsum dolor sit amet, consectetur adipiscing elit, 
159               sed eiusmod tempor incidunt ut labore et dolore magna aliqua.</p>
160
161            <!-- Las ecuaciones para la librería MathJax se encierran dentro de $$ y usan una notación propia
162                 de la librería (basada en el lenguaje LaTeX); atención: toda esta notación es específica de la
163                 librería y no es HTML: -->
164            $$
165              [\boldsymbol{\nu}_t,\boldsymbol{\xi}_t] = \mathcal{N}\left(x_t,r^{1}_{t-1},\ldots,r^{R}_{t-1}\right)
166            $$
167
168            <!--
169            $$
170              I = \begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}
171            $$
172            -->
173
174            <p>No obstante, lorem ipsum dolor sit amet, consectetur adipiscing elit, sed eiusmod tempor incidunt 
175               ut labore et dolore magna aliqua.</p>
176
177            <!-- El elemento <pre> representa texto preformateado.; el texto en este elemento típicamente 
178                 se muestra en una fuente fija, no proporcional (monoespacio), exactamente como es mostrado en 
179                 el archivo: los espacios dentro de este elemento también son mostrados como están escritos -->
180            <!-- El elemento <code> indica que el contenido es código fuente -->
181            <pre><code>
182              interface PrimaryCore {
183                boolean verifyDataLine();
184                void sendData(in sequence&lt;byte> data);
185                void initSelfDestruct();
186              }
187            </code></pre>
188
189          </article>
190          <article>
191            <h3>La memoria en las redes neuronales</h3>
192            <p>Tradicionalmente, las <em>redes neuronales</em> lorem ipsum dolor sit amet, consectetur adipiscing elit, 
193               sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 
194               nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.</p>
195
196            <!-- El elemento <figure> representa contenido independiente, a menudo con un título; si bien se
197                 relaciona con el flujo principal, su posición es independiente de este; por lo general, se trata
198                 de una imagen, una ilustración, un diagrama, un fragmento de código o un esquema al que se hace
199                 referencia en el texto principal, pero que se puede mover a otra página o a un apéndice sin que
200                 afecte al flujo principal -->
201            <figure>
202
203              <!-- El elemento <img> representa una imagen en el documento; su atributo src indica el URL de la
204                   imagen; el atributo obligatorio alt define un texto alternativo que describe la imagen -->
205                <img src="https://media.springernature.com/lw685/springer-static/image/art%3A10.1038%2Fnature20101/MediaObjects/41586_2016_Article_BFnature20101_Fig4_HTML.jpg"
206                     alt="Activaciones de los distintos cabezales de lectura/escritura 
207                          en una red neuronal derivable.">
208
209              <!-- El elemento <figcaption> representa un subtítulo o leyenda asociado al contenido del elemento 
210                   padre <figure>, pudiendo ser colocado como primer o último hijo -->
211              <figcaption>Esquema de una red neuronal derivable</figcaption>
212            </figure>
213          </article>
214        </section>
215
216        <!-- El elemento <aside> representa una sección de una página que consiste en contenido que está 
217             indirectamente relacionado con el contenido principal del documento (por ejemplo, comentarios
218             al margen o publicidad) -->
219        <aside>
220          <p>Al hilo de las reflexiones anteriores, lorem ipsum dolor sit amet, consectetur adipiscing elit, 
221             sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 
222             quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.</p>
223
224          <!-- Uso del componente web definido en la librería chessboard-element; el uso de style no está
225               recomendado normalmente -->
226          <chess-board position="start" style="width: 256px"></chess-board>
227        </aside>
228      </section>
229    </main>
230
231    <!-- El elemento <footer> representa un pie de página para el contenido de sección más cercano o el
232         elemento raíz de sección; un pie de página típicamente contiene información acerca del autor de la
233         sección, datos de derechos de autor o enlaces a documentos relacionados -->
234    <footer>
235      <p>© 2020, Franz de Copenhague</p>
236    </footer>
237  </body>
238</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.

Importante

Durante el ciclo de desarrollo de una aplicación web es habitual realizar cambios en los ficheros de la aplicación (por ejemplo en el documento HTML, en las hojas de estilo o en el código de JavaScript) y comprobar a continuación cómo queda la aplicación tras recargarla. En algunas ocasiones el navegador puede optar, pese a la recarga, por utilizar el contenido previo almacenado en la caché lo que nos puede llevar a la falsa impresión de que nuestros cambios no tienen efecto. Dentro de la pestaña Network de las Chrome DevTools existe una opción Disable cache que hace que el navegador ignore el contenido de la caché, pero solo mientras las herramientas de desarrolladores estén abiertas. Es recomendable tenerla siempre marcada.

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.

Puedes ver los valores de los bytes en UTF-8 de los diferentes bytes de una cadena en JavaScript ejecutando:

e=new TextEncoder(); s="Avión a reacción: ✈"; for (let i of s) console.log(`'${i}': ${e.encode(i)}`);

Nota

Cuando abres un documento con un editor de texto, el editor lee todos los bytes del fichero y los interpreta (y muestra) en base a la codificación con la que está configurado. Si, por ejemplo, el fichero se ha escrito con un programa que usa una codificación (llamémosla C1) en la que todos los caracteres ocupan un byte, pero se intenta mostrar con un editor configurado con una codificación (llamémosla C2) en la que todos los caracteres ocupan dos bytes, los caracteres mostrados probablemente no coincidirán con los originales, ya que el editor los agrupará de dos en dos. Además, al abrirlo con el editor, el fichero parecerá tener la mitad de caracteres que el original.

Por ejemplo, puede que los bytes F3 y A1 (representados en hexadecimal) en la codificación C1 correspondan al signo + y a la M, respectivamente, pero que en la codificación C2 la secuencia de dos bytes F3A1 corresponda al símbolo %, que sería lo que mostraría en pantalla el editor que usa C2. Es posible incluso que algunos pares de bytes no representen caracteres válidos en la codificación C2, porque en C2 no se usan todos los posibles valores para representar caracteres; en ese caso, el editor de texto puede hacer varias cosas dependiendo de su configuración: no mostrar nada (saltarse ese carácter) o mostrar un símbolo especial que identifique caracteres inválidos.

Nota

Los aspectos más relevantes mostrados en las diapositivas son:

  • UTF-8 es una codificación que asigna diferentes cantidades de bytes a los caracteres: algunos se representan con un byte, otros con dos, otros con tres y otros con cuatro bytes.

  • Cada uno de los 128 caracteres del ASCII (que se representan con un byte) se representan exactamente con el mismo byte en UTF-8. Los caracteres del ASCII se corresponden aproximadamente con los de un teclado estadounidense, por lo que no se incluyen entre ellos los caracteres acentuados, los kanjis del japonés o los emojis, entre otros muchos.

  • Los caracteres específicos del español o del catalán (á, à, ñ, Ñ, ç, Ç, etc.) ocupan dos bytes en UTF-8.

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 o el incorporado en Visual Studio Code.

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), nginx, LiteSpeed, 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 http.server

o con versiones más antiguas de Python:

python -m SimpleHTTPServer

La extensión LiveServer de Visual Studio Code permite lanzar el servidor local desde el propio editor de texto.

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)

Atención

En determinadas ocasiones el estándar de HTML permite omitir algunas etiquetas de clausura (por ejemplo, en ciertas ocasiones no es necesario cerrar la etiqueta </body> de antes de </html> y, aun así, el documento sigue siendo válido), pero son situaciones muy específicas, por lo que es más que recomendable crear siempre documentos que son válidos al margen de estas excepciones.

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án 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.

Nota

Las ventajas de trabajar con documentos validados no son solo para terceros que accedan a tu página, sino también para el desarrollador. Imagina que olvidas la primera línea de un documento HTML, es decir, la que reza <!DOCTYPE html>. Recuerda que hemos comentado que los navegadores son bastante laxos a la hora de mostrar los documentos y los procesan aunque no sean válidos, potencialmente introduciendo efectos colaterales inesperados. En concreto, la ausencia del tipo de documento pone al navegador en un modo especial que se denomina quirks. En este modo el navegador toma decisiones que lo alejan del estándar, intentando mostrar el documento como lo habrían hecho navegadores antiguos. En este modo, los márgenes o tamaños de ciertos elementos pueden variar, por ejemplo, pero ello puede cambiar de un navegador a otro.