Ultimo aggiornamento: 2024-04-01
Autore: Massimo Zancanaro
Termini di utilizzo: CC BY-NC 4.0
Questo manuale è preparato per il corso introduttivo a HTML e CSS dell'insegnamento Informatica ed elementi di programmazione I del corso di laurea triennale Interfacce e Tecnologie della Comunicazione dell'Università di Trento.
Gli obiettivi di apprendimento includono:
I prerequisiti per poter seguire questo corso comprendono una conoscenza di base dell'architettura logica del World-Wide Web, del concetto di Unified Resource Locator (URL) e del browser web come interprete e visualizzatore di documenti/pagine. Per la parte finale del modulo, è richiesta una competenza specifica di medio livello di Javascript che dovrebbe essere stata maturata alla fine del primo modulo del corso.
Il contenuto di questo corso e i documenti HTML di esempio sono disponibili nel repository github https://github.com/maxzancanaro/html_base/.
Il precursore di Internet è stato ARPAnet un modello di rete di computer che il Dipartimento della Difesa degli Stati Uniti ha iniziato a sperimentare a partire ufficialmente dal 1966. Il progetto ARPAnet era limitato a centri di ricerca militari (tra cui RAND) e poche università. Il progetto si basava su due idee specifiche. La prima era la necessità di costruire reti di computer in grado di trasmettere dati in modo affidabile anche su reti non affidabili (Baran, 1960), e in particolare, su infrastrutture danneggiate anche in modo molto grave: erano gli anni della Guerra Fredda e della paura di un attacco nucleare sul suolo americano. La seconda riguardava l'opportunità di usare i computer per facilitare il lavoro collaborativo di diverse persone (Licklider & Taylor, 1968).
Anche se il primo aspetto è stato quello che ha portato agli sviluppi tecnologici che hanno reso possibile l'enorme sviluppo di internet, è stata la seconda idea a determinare la possibilità della rivoluzione digitale come la intendiamo oggi. L'articolo di J. C. R. Licklider e Bob Taylor del 1968 è sorprendentemente attuale nella sua visione dell'informatica.
Il salto di qualità per ARPAnet si ha nel 1983 quando viene adottato ufficialmente un protocollo per la trasmissione dei dati inventato nel 1974 da Vincent Cerf (uno studente di dottorato di Stanford) e Bob Kahn di DARPA (Cerf & Kahn, 1974). Un protocollo è un insieme di regole e procedure realizzate in librerie software per permettere la comunicazione di dati tra dispositivi elettronici. Prima del 1983, ARPAnet usava protocolli diversi per le varie funzionalità della rete ma TCP/IP si rivelò molto efficiente e capace di realizzare appieno la prima delle due idee di base: trasmettere dati in modo affidabile e resistente alle interruzioni delle reti. TCP/IP implementa una modalità di packet-switched in cui i dati da trasmettere vengono divisi in parti (chiamate "pacchetti") che vengono mandati a diversi computer che poi li manderanno ad altri fino ad arrivare alla destinazione. La parte di protocollo che determina come un messaggio si divide in pacchetti e poi viene riassemblato a destinazione è il Transmission-Control Protocol (TCP), ma perché funzioni c'è bisogno che tutti i computer della rete siano in grado di conoscere "l'indirizzo" degli altri: di questa parte si occupa la parte chiamata Internet Protocol. Si può notare come all'epoca internet non era ancora il nome della rete ma semplicemente l'abbreviazione di "inter-network" cioè "tra diverse reti" in quanto gli indirizzi dovevano essere comuni tra le diverse sotto-reti di cui ARPANet era composta. Un indirizzo IP è un numero a 128 bit (inizialmente 32 bit) che identifica univocamente un computer nella rete: una parte del numero identifica la sotto-rete (o dominio) e le parti restanti sono usate all'interno del dominio per arrivare ad identificare specifici computer. Ai domini possono essere associati dei nomi significativi che sono memorizzati un database distribuito chiamato DNS (per Domain Name System).
Nel 1985, la National Science Foundation (NSF) lancia il progetto NSFnet che si basava sulla tecnologia ARPAnet (e sul protocollo TCP/IP) con l'obiettivo di collegare i centri di calcolo di diverse università per scopi scientifici, prima negli Stati Uniti e, negli anni seguenti, anche in Europa, Australia e Giappone. ARPANet viene ufficialmente dismessa nel 1990. Nel 1992, nel tentativo di sviluppare una rete internazionale e democratica, Vincent Cerf e Bob Kahn fondano un'associazione senza fine di lucro chiamata Internet Society con il mandato di sviluppare una tecnologia aperta e definita in modo partecipativo.
A partire dal 1986, le decisioni tecniche e di standardizzazione riguardo al protocollo TCP/IP e gli altri aspetti tecnici venivano gestite da un comitato di esperti chiamato Internet Engineering Task Force (IETF) nominati dalla NSF. Nel 1993, la IETF diventa un'organizzazione senza scopo di lucro basata negli Stati Uniti ma aperta alla partecipazione di esperti di tutto il mondo su base volontaria. Nel 1998, viene istituita un'altra organizzazione non-profit la Internet Corporation for Assigned Names and Numbers (ICANN) che si occupa di gestire i codici IP dei domini, cioè delle varie sottoreti.
Internet è una infrastruttura che regola solo il modo in cui diversi computer (o meglio, diverse sotto-reti di computer) possono interagire tra loro. Usando questa infrastruttura, possono essere implementati diversi tipi di servizi informatici (tra cui l'email).
Il World Wide Web è uno di questi servizi informatici nato per esigenze specifiche al CERN di Ginevra nel 1989 e poi cresciuto fino a diventare esso stesso un infrastruttura su cui costruire altri servizi (tra cui una re-implementazione del servizio originale di email di internet).
Le basi di quello che oggi è il Web sono state definite nel 1989 da un tecnico informatico del CERN di Ginevra, Tim Berners-Lee, per facilitare la condivisione di documenti tra gli scienziati del centro di ricerca usando la rete Internet (2024 CERN). La necessità di Berners-Lee era quella di costruire uno strumento per visualizzare semplici ipertesti, cioè documenti di testo collegati tra loro. All'epoca, c'erano diverse definizioni di ipertesto (si veda ad esempio Conklin, 1987) e Berners-Lee ha adottato una versione semplificata adatta per i suoi scopi: ha definito un semplice linguaggio di annotazione di testi (che vedremo nel dettaglio nel resto di questo manuale) e un'estensione del protocollo TCP/IP per scambiarsi questo tipo di documento (il protocollo HTTP che sta Hyper-Text Transfer Protocol). Ha anche esteso la definizione di "indirizzo" internet per poter specificare non solo quale sotto-rete/computer raggiungere ma anche identificare lo specifico documento definendo lo Unified Resource Locator (URL) come estensione dell'indirizzo IP. Al nome del dominio, viene aggiunto il percorso per raggiungere lo specifico documento (o pagina) dell'ipertesto (in realtà, come si vedrà in seguito, l'URL può anche contenere dei parametri che vengono interpretati per adattare il contenuto).
A differenza dell'infrastruttura internet, nel Web non tutti i dispositivi sono allo stesso livello ma si prevede che alcuni dispositivi (server) mantengano e distribuiscano gli ipertesti mentre altri (client) possano richiederne le pagine per visualizzarne. All'inizio del web, un client non faceva nient'altro che visualizzare i documenti e "percorrere" i collegamenti ipertestuali per cui veniva chiamati browser (dall'inglese "to browse" che significa specificatamente "sfogliare").
Il CERN ha reso disponibile in modo aperto il protocollo HTTP e la definizione di HTML nel 1993. Nel corso dei decenni successivi, il Web è evoluto progressivamente da strumento per visualizzare (semplici) ipertesti ad una infrastruttura per definire servizi digitali avanzati, eseguire applicazioni software e, in alcuni casi, addirittura sistemi operativi (come ad esempio Chrome OS di Google). Anche se la visualizzazione di documenti HTML (anche nella forma di applicazioni software) è ancora uno degli aspetti fondamentali, i server web forniscono anche altri tipi di servizi utilizzabili anche applicazioni non web (si pensi ad esempio alla differenza tra accedere alla mail dal browser o accedervi da un applicazione nativa Android o iPhone): non tutti i web client oggi sono web browser.
È però importante ricordare che il Web non esaurisce tutti i servizi disponibili e realizzabili su internet: ad esempio, tutti i servizi di IoT (Internet-of-Things) e gran parte della gestione dei dispositivi wearable, così come i servizi di streaming (almeno parzialmente) non dipendono dall'infrastruttura Web.
internet: un insieme di computer (o meglio dispositivi) che sono in grado di connettersi tra loro e di scambiarsi informazioni usando specifiche codifiche (protocolli): in particolare, TCP/IP e i protocolli da esso derivati.
dispositivo: un qualunque hardware che contiene una serie di programmi per accedere ad internet tra cui un client (o più client); per il client è importante conoscere le caratteristiche del dispositivo: risoluzione, media, ...).
server web: un computer che riceve richieste sul protocollo HTTP e restituisce pagine web e a volte altre cose: nel corso degli anni, il protocollo HTTP è stato esteso per coprire necessità sempre più complesse rispetto a quelle degli ipertesti e sono stati sviluppati altri (meta-)linguaggi più orientati allo scambio di dati come XML e JSON che possono essere trasmessi sul protocollo HTTP oltre all'HTML.
HTTP: HyperText Transfer Protocol una codifica inizialmente definita per trasmettere in Internet un tipo particolare di dati, i documenti ipertestuali ma attualmente il protocollo forse più diffuso per trasmettere vari tipi di dati strutturati.
URL: Unified Resources Locator un modo specifico di nominare gli oggetti sul web usando il protocollo HTTP; un URL ha la forma https://dominio/path/documento. Per gli ipertesti (e per le applicazioni web-based) il documento è un file di tipo HTML mentre per la trasmissione di altri dati strutturati si usano altri linguaggi basati su XML e JSON (o altri formati testuali)
client web: una applicazione software che utilizza HTTP per interrogare uno (o più) server web per ottenere dati in formato HTML o in altri formati utilizzati da questo protocollo.
browser web: un tipo particolare di client web che interroga un server web per ricevere documenti HTML e visualizzarli (o renderli in un altre modalità) usando le direttive in uno o più file CSS ed eseguendo del codice Javascript.
Un linguaggio di markup è un modo formale e strutturato di annotare un testo per identificare le varie parti al fine di usare queste informazioni per elaborare il testo in modo automatico: di solito (anche se non esclusivamente) per formattare il testo al fine di presentarlo su uno specifico media.
Anche se in senso generale, i linguaggio di markup si possono considerare linguaggio di programmazione in quanto servono a specificare ad un computer come operare su dei dati, la differenza tra i linguaggi di markup e i linguaggi di programmazione è che mentre quest'ultimi sono usati per dare istruzioni per eseguire determinate funzioni, i primi servono per annotare la struttura di un testo al fine di descriverne le parti (si veda, Hemmendinger, 2023; Britannica Editors, 2024).
Oltre allo HTML, che vedremo in seguito, esistono molti altri linguaggi di markup. Ad esempio, SGML (Standard Generalized Markup Language), da cui HTML deriva, è stato definito per creare classi di linguaggi di markup, in particolare per annotare strutture di testi letterari a fini di archiviazione e indicizzazione e come passaggio preliminare per analisi bibliografiche. XML (eXtended Markup Language) è una forma semplificata e più strutturata di SGML usata per annotare strutture di dati e automatizzare i processi di analisi. Markdown e LaTex vengono usati per definire aspetti specifici di formattazione e sono molto usati in ambito editoriale.
Un linguaggio di markup consiste in una serie di elementi extra-testuali che vengono inseriti nel testo per annotare (o marcare) gli aspetti che si ritengono rilevanti della struttura. La figura 1.1 mostra un esempio di annotazione della struttura di una antologia di poesie. Nell'esempio, si suppone che un'antologia (anthology) sia formata da una a più poesie (poem) ognuna delle quali composte da un numero variabile di stanze a loro volta composte da un numero variabile di linee (line).
Figura 1.1 Esempio di testo annotato con SGML (da Sperberg-McQueen & Burnard, 1999; part 1, chapter 2) |
Nei linguaggi definiti da SGML e dai suoi derivati (tra cui HTML), i principali elementi extra-testuali per l'annotazione di chiamano tag e sono costruiti come parole racchiuse tra parentesi angolari (ad esempio, <stanza>). Ogni tag ha anche una forma finale costruita nello stesso modo ma con una barra dopo la parentesi angolare iniziale (ad esempio </stanza>). Per annotare una determinata parte di testo con un certo tag, si posiziona il tag di apertura prima dell'inizio del testo e il tag di chiusura alla fine. Una porzione di testo, non può contenere annotazione "incrociate" cioè i tag devono essere chiusi nell'ordine in cui sono stati aperti. La figura 1.2 mostra alcuni esempi.
Figura 1.2 Esempio di testo con due annotazioni in SGML: i tag non vanno mai "incrociati" (in altri termini, ogni tag aperto all'interno di un altro tag va chiuso prima del precedente) |
Non tutti i linguaggi di markup sono basati sulla struttura dei tag ma sia HTML che XML, essendo basati su SGML, usano lo stesso approccio. XML (come anche SGML) è un meta-linguaggio, cioè si usa per definire linguaggi di markup: non esistono tag predefiniti ma viene definita solo l'architettura generale e le regole di composizione dei tag. XML è molto meno complicato di SGML ed è stato pensato per essere più interpretabile e gestibile in modo più efficiente.
Diversamente, HTML è uno specifico linguaggio e quindi l'insieme dei tag è definito a priori così come il loro significato. HTML è stato inizialmente definito a partire da SGML e recentemente invece basato su XML (anche se quest'ultimo si chiama più propriamente XHTML).
Ogni linguaggio di markup definisce formalmente le regole di composizione delle annotazioni all'interno di un testo. Ha poi bisogno di un interprete, cioè di un programma (o una libreria di programmi) per estrarre le annotazioni da uno specifico testo e applicare le operazioni necessario per la gestione del documento (indicizzazione, analisi, visualizzazione, ecc.). Nel caso di HTML, questo interprete è integrato all'interno di ogni browser internet e le operazioni sono quelle di visualizzare il testo rispettando la sua struttura, cioè usando il tipo di carattere e i colori appropriati per i titoli a diversi livelli, la spaziatura dei caratteri ecc., nonché di permettere di "navigare" tra le pagine dell'ipertesto seguendo i link ipertestuali definiti (tramite uno specifico tag) all'interno del documento.
HTML è uno specifico linguaggio di markup per annotare la struttura di ipertesti: la sigla HTML sta per Hyper-Text Markup Language. È stato definito nel 1989 da un tecnico informatico del CERN di Ginevra, Tim Berners-Lee, per facilitare la condivisione di documenti tra gli scienziati del centro di ricerca usando la rete Internet. La definizione dell'HTML e del protocollo di trasmissione dati HTTP (Hyper-Text Transfer Protocol) è alla base del World Wide Web (come brevemente discusso nell'introduzione).
HTML è uno standard inizialmente mantenuto dal World Wide Web Consortium (W3C) e dal 2018, è gestito da un consorzio di aziende chiamato WHATWG, a cui partecipano tra gli altri anche Apple e Google. Lo standard è in formato aperto e soggetto a continue migliorie tramite contributi e commenti.
HTML consiste in un insieme predefinito di tag che in generale sono intesi descrivere la struttura del testo e non come deve essere rappresentata (anche se con qualche eccezione, come vedremo nel seguito). Ogni interprete HTML, decide in modo autonomo in che modo visualizzare (o rendere in altre modalità) il testo rispettando la sua struttura e anche ottimizzando la resa rispetto al dispositivo o ad altre condizioni. Per esempio, in un cellulare i caratteri da usare dovranno essere necessariamente più piccoli che in uno schermo da computer, oppure per utenti con disabilità visive sarà necessario leggere il testo e rendere la struttura con commenti audio. Anche se ogni browser ha delle regole specifiche e predefinite, queste possono essere specificate in modo più dettagliato usando un linguaggio di specifiche (non di markup) chiamato Cascade Style Sheet (CSS) che vedremo sotto.
Come ogni linguaggio derivato da SGML, i tag sono parole racchiuse tra parentesi angolari. Per annotare una porzione di testo usando un certo tag, la si racchiude tra il tag di apertura e la sua versione di chiusura. Ad esempio, per specificare che una porzione di testo deve essere resa in modo enfatico, la si annota usando il tag `<em>` (si veda figura 2.1).
Alcuni tag non hanno bisogno di includere del testo: per esempio, se vogliamo indicare la presenza di una linea di divisione tra due paragrafi, si può usare il tag `<hr>` (che sta per horizontal rule). Questo tipo di tag, che ha solo l'apertura e non la chiusura si chiama self-closing tag, nella sintassi più stringente di XHTML (derivata da XML invece che da SGML), si scrive più propriamente come `<hr/>`. Si veda la figura 2.1.
Figura 2.1. Esempio di un tag di annotazione di una porzione di testo e di un tag "self-closing" |
Attualmente, l'HTML non è solamente usato per fare ipertesti (cioè le pagine web) ma anche, e forse soprattutto, per definire la struttura grafica delle web app (applicazioni che vengono eseguite all'interno di un browser) e, in certi casi, anche per le interfacce grafiche di altre applicazioni software (cellulari, smartwatch, chioschi, ecc.).
La versione corrente HTML5 include non solo l'HTML ma anche la definizione del linguaggio di specifiche CSS e il linguaggio di programmazione Javascript che viene usato per modificare la struttura in modo automatico.
Seguendo la sintassi SGML (e anche di XML), i tag di HTML possono avere una struttura interna, oltre a contenere porzioni di testo.
Un elemento importante della struttura interna è l'uso delle coppie attributo/valore per specificare dei parametri aggiuntivi rispetto al significato del tag. Ad esempio, per inserire un'immagine nel documento si usa il self-closing tag `<img>` ma bisogno, almeno, specificare il nome del file in cui si trova l'immagine: per farlo, si usa l'attributo src (per "source") indicando come valore il nome del file (si veda la figura 1.2).
Figura 2.1 Esempio di attributi e valori per specificare parametri dei tag HTML |
Due attributi particolari sono id e class. Servono ad identificare in modo univoco la porzione di testo annotata con un specifico tag o le porzioni di testo annotate da uno specifico tag. Questa possibilità è molto utile per modificare le proprietà di specifiche porzioni di testo usando CSS o per operare delle modifiche in parti specifiche del documento usando Javascript, come si vedrà nel seguito.
Un documento HTML è formato da due parti strutturali: una head che contiene informazioni di meta-livello (come vedremo sotto in dettaglio) e un body che contiene il testo opportunamente annotato con altri tag (che saranno introdotti nel seguito).
I documenti HTML sono file di testo e di solito vengono salvati con estensione .html. L'estensione del file non è in genere rilevante per una corretta interpretazione del contenuto ma diversi editor di testo riconoscono e adattano la visualizzazione del documento partendo dall'estensione. In questo modo, gli editor possono ad esempio visualizzare i tag con un colore diverso rispetto al testo da annotare, indentare in modo appropriato i tag e suggerire quale tag è il prossimo da chiudere, facilitando così la preparazione dei documenti HTML.
La figura 3.1 presenta lo scheletro di un annotazione HTML. L'indentazione dei tag seguendo la struttura gerarchica (cioè, le annotazione incorporate in altre annotazioni sono spostate più a destra) non è richiesta dal linguaggio di markup ma facilita molto l'annotazione di documenti, specialmente quando la struttura inizia a diventare un po' complessa.
<!DOCTYPE html>
<html>
<head>
<!-- qui vanno inserite informazioni di meta-livello -->
</head>
<body>
<!-- qui va inserito il testo e le annotazioni di struttura -->
</body>
</html>
Figura 3.1 Struttura di base di un documento HTML
Le sequenze di caratteri che iniziano con `<!` non sono dei tag propriamente detti ma delle direttive che vengono fornite all'interprete per gestire casi particolari. Nell'esempio sopra, se ne trovano due: `<!DOCTYPE html>` e `<!-- -->`.
`<!DOCTYPE html>` è una direttiva che indica al browser (o in genere all'interprete) che il documento è in formato HTML. La maggior parte dei browser funziona anche in assenza di questa indicazione ma in alcuni casi è importante che sia. Si possono opzionalmente anche aggiungere dettagli sulla versione specifica.
`<!-- -->` è una direttiva che indica che il testo incluso è un commento (e quindi non è tecnicamente una parte del documento che viene annotata). Il browser (o l'interprete) semplicemente ignora tutto ciò che viene scritto all'interno delle due parti (si veda l'esempio sopra).
La sezione head (quella compresa tra i tag `<head>` e `</head>`) dovrebbe essere necessariamente innestata all'interno della sezione html e prima della sezione body. I browser moderni sono in generale abbastanza flessibili da riconoscere queste due sezioni comunque siano disposte nel documento ma è possibile che alcune parti vengano interpretate in modo diverso dai diversi browser o che alcuni tag interni non vengano poi riconosciuti.
All'interno della sezione head si possono inserire solo alcuni tag specifici e in generale non si mette testo.
Attenzione: la maggior parte dei browser visualizza un eventuale testo nella sezione head come fosse inserito prima della sezione body ma questo crea problemi nel caso si voglia accedere alla struttura del documento usando Javascript, come spiegato in seguito).
I tag principali che compaiono nella sezione head sono i seguenti:
`<title>` definisce il titolo del documento. Attenzione alla differenza tra il titolo di un documento (che viene di solito visualizzato nella barra del browser o del tab in cui il documento viene aperto) e le intestazioni (a volte genericamente chiamate titoli) che si trovano nel body e vengono visualizzate nella pagine (si veda il capitolo seguente).
Figura 4.1 Esempio di documento HTML senza nessuna formattazione ma con un head che contiene il titolo (attenzione a notare dove il titolo viene visualizzato!) |
`<meta>` viene usato per inserire direttive di meta-livello, utili sia per visualizzare il documento (ad esempio quale gruppo di caratteri utilizzare) che per archiviare i documenti HTML in database (come la specificazione dell'autore o dell'autrice) e per indicizzare il contenuto sui motori di ricerca. Gli attributi più usati sono riportati nella figura 5.2. L'attributo charset serve per definire lo specifico gruppo di caratteri (in particolare, se si usano caratteri non latini). L'attributo viewport impone che la dimensione del display sia uguale a quella del dispositivo: in questo modo le pagine vengono visualizzate nel modo più appropriato (per usi molti particolari e avanzati, è necessario modificare questa impostazione che comunque andrebbe sempre specificata). L'attributo meta è più generico e richiede sempre di specificare anche l'attributo content: il primo definisce la categoria (ad esempio, author o keyword e il secondo specifica i valori della categoria).
<head>
<title>Template</title>
<meta name="description" content="full head template">
<meta name="keywords" content="HTML, learning">
<meta name="author" content="Massimo Zancanaro">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
</head>
Figura 4.2 Struttura di base di un documento HTML
Nella sezione head, vengono anche definiti gli stili sia interni che esterni al documento che gli script in Javascript, anche questi possono essere interni o esterni al documento. Entrambi questi aspetti saranno discussi più approfonditamente nei capitoli seguenti.
Per una specifica completa si può vedere la sezione 3.2.5.2.1 del Living Standard)
La sezione body, racchiusa tra i tag `<body>` e `</body>` comprende il documento annotato. La maggior parte dei tag HTML si applica in questa sezione. In questo capitolo vedremo i tag di formattazione (formatting) e di impaginazione (layout). Alcuni aspetti più avanzati che richiedono combinazioni di tag per fare liste, tabelle, e mappa cliccabili) saranno trattati nei capitoli successivi.
In generale, il testo che si trova nella sezione body viene semplicemente visualizzato usando il carattere predefinito (questo può comunque essere modificato usando CSS, come vedremo). In generale, indipendentemente da come il testo viene scritto nel file, viene poi visualizzato come una singola linea con spaziature appropriate tra le parole e una divisione in righe che dipende dalla grandezza della finestra di visualizzazione (si veda figura 6.1).
In generale, il testo dei file HTML è scritto in caratteri normali (nel charset definito dal campo meta charset, altrimenti non viene visualizzato bene: questo è particolarmente importante per alfabeti non latini o, a volte, anche per le lettere accentate in italiano). È però importante notare che alcuni caratteri non si possono scrivere: in particolare le parentesi angolari vengono interpretate come l'inizio o la chiusura di un tag e se usate come caratteri del documento creano confusione al browser. In modo simile, gli spazi vuoti vengono ignorati dal browser. Per visualizzare in modo appropriato parentesi angolari e spazi vuoti si usano le cosiddette character entities: sono codici che iniziano con un simbolo `&` e terminano con un punto e virgola, e racchiudono una parola che indica il carattere da visualizzare. Le character entities fondamentali da ricordare sono: `<` per visualizzare (sta per less than) `<` , `>` per visualizzare `>` (sta per greater than) e ` ` per uno spazio (sta per non-breaking space, si chiama così perché è utile per inserire forzatamente uno spazio tra due parole impedendo quindi che vengano separate da un'interruzione di riga). Ovviamente, anche il carattere `&` è un carattere vietato, in quanto segnala una character entity e per inserirlo si usa il `&`
Le character entities si usano anche per visualizzare caratteri non standard o caratteri al di fuori del charset utilizzato. L'elenco completo si può trovare ad esempio nella pagina di Wikipedia List of XML and HTML character entity references.
Figura 6.1 Dal file HTML al documento HTML (da notare l'uso di character entities) |
I tag di formattazione (formatting) di porzioni di testo si dividono in due categorie: quelli che indicano in modo specifico quale formattazione applicare (grassetto, italico, ecc.) e quelli che indicano la funzione logica che si vuole ottenere (enfasi, cancellazione, ecc.). Nelle prime versioni di HTML, erano presenti solo i primi in quanto la funzione principale era la visualizzazione di un documento.
Oggi si preferisce usare la formattazione logica perché un documento potrebbe essere reso in modalità diverse (audiolettura, o visualizzazione su formati diversi). Ad esempio, la porzione di testo HTML `questo testo è <b>importante</b>` viene visualizzato mettendo in grassetto la parola "importante": "questo testo è importante". Usando il tag `<strong>` invece che `<b>`, si ottiene lo stesso risultato ma si rende più esplicito il significato comunicativo che si vuole dare alla parola. Un interprete potrebbe quindi meglio rappresentare questo significato laddove il grassetto non possa essere usato (come nel caso di una audiolettura dove andrebbe stressata la voce sulla parola per rendere l'importanza), oppure possa non essere efficace (ad esempio, nei tipi di carattere usato per facilitare la lettura alle persone con dislessia, il grassetto non è reso bene perché i caratteri sono già molto spessi, in questo caso, il browser potrebbe sottolineare la parola o visualizzarla più grande).
Inoltre, come vedremo in seguito, le formattazioni specifiche si possono fare in modo più efficiente usando CSS. Per questo motivo, diversi tag di questa categoria, anche se non tutti, sono "deprecati" (deprecated) in HTML5: significa che sono ancora utilizzabili ma se ne sconsiglia l'uso perché nelle successive versioni potrebbero essere eliminati e quindi rendere il documento non più visualizzabile sui nuovi browser.
`<b> ... </b>`: visualizza il testo in grassetto;
`<i> ... </i>`: visualizza il testo in italico;
`<u> ... </u>`:testo viene visualizzato con una sottolineatura;
`<s> ... </s>` e `<strike> ... </strike>`: il testo annotato viene visualizzato come barrato (in HTML5, entrambi i tag sono deprecati).
`<small> ... </small>` : il testo annotato viene visualizzato con caratteri di dimensioni più piccole rispetto al resto del documento;
`<sub> ... </sub>` e `<sup> ... </sup>`: il testo viene visualizzato come pedice o apice, rispettivamente.
` <strong> ... </strong>`: visualizza il testo in formato più accentuato, di solito viene usato il grassetto;
`<em> ... </em>`: visualizza il testo dando maggiore enfasi, di solito viene usato l'italico;
`<del> ... </del>` e ` <ins> ... </ins>` : indicano rispettivamente un testo da cancellare, di solito viene visualizzato come testo barrato, e come testo da aggiungere, di solito visualizzato come sottolineato;
`<mark> ... </mark>`: il testo viene evidenziato, di solito viene usato un colore di sfondo giallo;
`<cite> ... </cite>`: serve per riportare citazioni, di solito il testo viene scritto in italico;
`<code> ... </code>`: il testo annotato viene visualizzato come fosse un pezzo di codice scritto in un linguaggio di programmazione (attenzione: non significa che il codice venga eseguito davvero); di solito viene usato un carattere di tipo monospace;
`<kbd> ... </kbd>` : il testo viene riportato in un formato che dovrebbe rende evidente che si tratta di un input da tastiera, anche in questo caso viene di solito usato un carattere monospace;
Un tag molto importante, come vedremo in seguito, è `<span>` che è stato introdotto per denotare generiche porzioni di testo. Un'annotazione con questo tag non viene visualizzata in nessun modo particolare e il testo appare esattamente uguale a quando non la si usa. La differenza è che usando questo tag, si potranno poi in CSS definire formattazioni specifiche su specifiche porzioni di testi all'interno di un blocco (e quindi, si potranno ridefinire tutti i tag di formattazione visti sopra).
I tag di impaginazione (layout) dei paragrafi includono un gruppo di tag per annotare e visualizzare i titoli, un gruppo di tag per denotare i blocchi di testi, tra cui i paragrafi e infine dei tag per definire layout particolari.
I tag per annotare e visualizzare i titoli di diverso livello sono `<h1>`, `<h2>`, e così via fino ad `<h6>`. I vari browser determinano per ognuno quale tipo di carattere, formato, grandezza e colore utilizzare (si veda figura 6.1). Queste proprietà sono comunque personalizzabili usando CSS.
Figura 6.2 Visualizzazione in Chrome dei 6 livelli di titolo (heading) in HTML |
Nell'HTML originario, era stata introdotta l'annotazione `<p>...</p>` per denotare porzioni di testo che rappresentano un paragrafo. Il testo all'interno di un paragrafo è rappresentato come una unica linea, indipendentemente da come viene scritto nel file e il browser si occupa di andare a capo quando necessario, dipendentemente dalla larghezza della finestra. Inoltre vengono aggiunte delle spaziature appropriate prima e dopo ogni paragrafo (figura 6.3).
Figura 6.3 Gestione automatica dei paragrafi (tag `<p>...</p>` in HTML |
Benché ancora molto usato per annotare documenti, il tag `<p>` è poco versatile perché impone una formattazione difficile poi da gestire in modo personalizzato (come vedremo più avanti). Nelle nuove versioni di HTML, è stata introdotta l'annotazione `<div>...</div>` per rappresentare generici blocchi all'interno di un documento. La rappresentazione visuale standard delle porzioni `<div>` è simile a quella per `<p>' con la differenza che i blocchi di testo non vengono tra loro separati (si veda figura 6.4). Nell'usare il tag ‘<div>' si potrà poi gestire la spaziatura, l'indentazione o altre proprietà di impaginazione usando CSS.
Figura 6.4 Differenza tra il tag `<p>` e il tag `<div>` |
Il tag `<pre>` è un altro modo di annotare blocchi di testo, funziona come il `<div>` in quanto non aggiunge spaziatura ma, a differenza di quello, non mette neppure il testo sulla stessa riga e lo lascia con le spaziatura del testo che si trova nel file.
Infine, `<blockquote>` si usa per fare una citazione, cioè per riportare un pezzo di testo preso da un'altra fonte (attenzione alla differenza con `<cite>`, in Italiano la parola citazione copre entrambi i significati ma in Inglese sono diversi). Viene di solito visualizzato con caratteri italici e l'intero paragrafo indentato a destra.
Due tag di tipo self-closing spesso usati che assomigliano più a direttive che ad annotazioni, ma sono comunque molto utili, sono `<br>` (o `</br>`) che interrompe una riga andando a capo e `<hr>` (o `</hr>`) che inserisce una linea divisoria orizzontale.
Infine, il tag più importante, almeno dal punto di vista simbolico, è quello che permette di collegare diversi documenti (o, diverse parti di un documento) per realizzare un ipertesto. Un ipertesto, tecnicamente equivale ad un documento la cui struttura non è lineare ma ha la forma di un grafo (figura 6.5).
Figura 6.5 Una delle prime rappresentazioni del concetto di ipertesto (da Conklin, 1987) |
A differenza di altri linguaggi per definire ipertesti, HTML è stato tenuto volutamente molto semplice. L'unico modo per definire strutture ipertestuali è usare il tag è `<a> ...</a>` che sta per anchor, ossia la porzione di testo a cui si connette (o, appunto, si "àncora") il collegamento (link). I collegamenti possono essere esterni (ad altri documenti o pagine) oppure interni verso altre porzioni dello stesso documento.
La destinazione del collegamento viene specificata con l'attributo href. Se il valore di questo attributo è un nome di un file, questo viene aperto, se invece è un URL viene caricato via internet. Per fare un collegamento interno, viene invece indicato un codice identificativo prefisso dal carattere #. Lo stesso codice deve essere poi indicato in un tag dello stesso documento usando l'attributo id: quando si clicca su l'ancora, la visualizzazione del documento scorre fino a rendere visibile il tag a cui è stato assegnato l'id.
Figura 6.2 Uso di collegamenti ipertestuali esterni ed interni con il tag `<a>` |
Un attributo importante per il tag `<a>` è target che specifica come aprire il nuovo documento ipertestuale: i principali valori sono: _self (il valore predefinito) che apre il documento nella stessa finestra del browser del documento di partenza, _blank lo apre in un'altra finestra o tab del browser; le opzioni _top e _parent sono di solito simili a _blank tranne quando si usano i frame che non vengono però trattati in questo manuale in quanto danno problemi di usabilità e di sicurezza (e sono infatti "deprecati" in HTML5).
Il tag `<a>` permette anche l'uso dell'attributo title che viene in generale visualizzato come tooltip di aiuto ma può anche essere utile per migliorare l'accessibilità del documento.
Come forse appare evidente dalle spiegazioni precedenti, il linguaggio HTML si è andato evolvendo da un linguaggio con uno specifico obiettivo di visualizzare un testo formattato su uno schermo ad un linguaggio per annotare la struttura logica di testi. Lo si vede dalla distinzione tra i diversi tipi tag di formattazione (enfasi e citazione sono entrambi realizzati con l'italico ma specificare l'uso dell'italico fa perdere la distinzione logica tra questi due usi), dall'introduzione di un tag generico `<span>` per porzioni di testo, e anche dalla necessità di avere un tag generico per annotare un blocco di testo rispetto allo specifico paragrafo. Questa evoluzione è sempre più marcata a partire dall'introduzione del linguaggio di specifiche CSS (con HTML4).
Nella versione attuale, HTML5, questo aspetto si è ulteriormente evoluto, anche in considerazione che il web non è più un insieme di documenti ma vengono sempre più spesso realizzate vere e proprie interfacce grafiche all'interno di un browser. HTML5 ha quindi introdotto nuovi tag che rappresentano strutture più ad alto livello di un documento, tra cui:
`<header>` definisce l'intestazione di un documento (da non confondersi comunque con la sezione `<head>` del documento HTML);
`<nav>` definisce la sezione di navigazione;
`<article>` rappresenta un pezzo di contenuto indipendente che può essere spostato e riutilizzato in diverse parti del documento;
`<section>` definisce una sezione di un documento, che in genere include un `<header>` specifico
`<aside>` rappresenta del contenuto che è collegato ma separato dal resto, come ad esempio un barra laterale o un menu contestuale;
`<footer>` rappresenta il piè di pagina;
`<main>` definisce l'area principale del documento in cui di solito si mettono le varie `<section>`
`<figure>` rappresenta una sezione indipendente per figure e tabelle (da non confondere con i tag per inserire figure e tabelle che vedremo nei prossimi capitoli).
`<figcaption>` rappresenta la legenda di una `<figure>`
`<details>` definisce una porzione di documento che fornisce informazioni aggiuntive (di solito che viene nascosta e mostrata a seconda delle esigenze)
`<summary>` simile a `<details>`, definisce un riassunto di un determinato contenuto;
Per nessuno di questi è però prevista alcuna specifica realizzazione visuale (esattamente, come per `<span>') perché questo aspetto viene gestire in modo separato nei CSS.
Come si può notare, i nuovi tag riprendono nei loro nomi (e nella loro definizione) i concetti di base dell'editoria, infatti l'obiettivo è di raggiungere la completa separazione tra la struttura logica di un documento (demandata alla linguaggio di markup HTML) e la sua rappresentazione in un determinato media (demandata alle specifiche CSS).
La possibilità di visualizzare liste di elementi è un aspetto importante delle pagine web. Anche se tecnicamente, si possono fare liste mettendo in sequenza dei blocchi di `<div>` (e poi eventualmente formattarli con CSS), HTML mette a disposizione due annotazioni specifiche con una formattazione standard: le liste ordinate (e numerate) e quelle non ordinate.
Le liste ordinate sono annotate con il tag `<ol>..<\ol>` (che sta per ordered list) e gli elementi della lista con il tag `<li>` (che sta per list item). Le liste ordinate vengono indentate leggermente a destra e usano i numeri arabi. Questa e altre formattazioni possono essere personalizzate usando CSS, come vedremo in seguito.
Per le liste non annotate si usa il tag `<ul>..<\ul>` (che sta per unordered list) e per gli elementi si usa ancora il tag `<li>`. Anche le liste non ordinate sono leggermente indentate a destra e di default viene usato un cerchio pieno, ma anche questi sono parametri che possono essere modificati con CSS.
È anche possibile innestare liste dentro ad altre liste, inserendole all'interno delle annotazioni di un elemento `<li>...</li>`.
La figura 8.1 illustra le varie possibilità.
Figura 8.1 Varie possibilità per visualizzare liste (e liste innestate in liste) |
Altri aspetti fondamentali per un qualunque strumento di tipo editoriale includono la possibilità di fare delle tabelle, includere delle immagini. Per uno strumento editoriale online, è rilevante anche considerare la possibilità di rendere attive le immagini trasformandole in mappe interattive. Tutte queste possibilità sono incluse nell'HTML di base senza la necessità di usare CSS o funzioni di Javascript (anche se, come per tutte le altre caratteristiche di base, si può poi personalizzarne la resa visuale).
Le tabelle sono strutture visuali che organizzano dei dati testuali in un certo numero di righe e un certo numero di colonne. All'incrocio di una riga e una colonna si ha una cosiddetta "cella" che contiene il testo da visualizzare. Di solito, le celle della prima riga contengono i titoli delle colonne, e in questo caso la riga si chiama "testata" (header) della tabella.
Le tabelle vengono gestite usando i tag per le righe `<tr>` (per table row) e quelli per le celle `<td>` (per table data) oppure `<th>` (per table header) innestati all'interno del tag `<table>...</table>` che fornisce il contesto per visualizzare e per riferirsi (ad esempio con un attributo id) ad una tabella. La figura 8.2 presenta un esempio.
Un punto di attenzione è che le tabelle non hanno bordo ma lo si può aggiungere con l'attributo border del tag `<table>`. Anche in questo caso, personalizzazioni più efficaci sono possibili con l'uso di CSS, come vedremo più avanti.
Figura 8.2 Esempio di una tabella con uso di rowspan e colspan |
Come si vede nella figura 8.2, gli attributi colspan e rowspan possono essere usati per avere celle che si distribuiscono su più righe o su più colonne.
Per inserire un'immagine in HTML, si usa il tag self-closing `<img>` (o, `<img/>`). La specificazione di quale immagine visualizzare è fornita nell'attributo src come nome di file o come URL.
<img src="img.jpg"/>
<img src="http://.../img.jpg"/>
<img src="img.jpg", alt="qui c'è un'immagine di un gatto", title="il gatto", height="xxx", width="xxx"/>
Figura 8.3 Template per inserire un'immagine con il tag `<img>` (si veda l'HTML per un esempio concreto)
Il tag `<img>` permette anche l'uso di altri attributi opzionali. L'attributo alt è molto importante per l'accessibilità in quanto è inteso fornire una descrizione testuale dell'immagine per i dispositivi di lettura per le persone non vedenti. L'attributo title invece è il titolo dell'immagine e, per i browser dei computer desktop, viene visualizzata quando il mouse passa sopra l'immagine. Infine, si possono specificare gli attributi width e height dell'immagine che hanno una doppia funzione: da una parte, pre-calcolano lo spazio occupato dall'immagine e la possono quindi caricare in parallelo al resto del documento (è importante per immagini molto grandi e per connessioni lente); dall'altra parte, possono essere usati per ridimensionare l'immagine in fase di caricamento (ma non è una tecnica computazionalmente molto efficiente).
Essendo pensato principalmente in ambiente interattivo e multimediale, HTML ha un supporto (seppur limitato) per creare dei link ipertestuali anche a partire da immagini.
La figure 9.1 illustra lo schema per costruirle. Si parte dall'immagine che vogliamo usare per definire le aree cliccabili che diventeranno àncore per i link ipertestuali. Le aree vengono poi definite in una struttura separata (detta mappa) denotata dai tag `<map>...</map>`.
Figura 9.1 Template per definire immagini con àncore ipertestuali (chiamate in HTML mappe) |
Per collegare l'immagine alla mappa, si usa un identificatore, cioè una stringa di caratteri che può essere costruita a piacere ma deve essere unica all'interno del documento. Questo identificatore viene specificato con l'attributo name nel tag `<map>` e viene poi usato nel tag `<img>` nell'attributo usemap. È importante notare che quando si usa come identificativo si usa la stringa normale mentre quando si usa come riferimento si deve anteporre il carattere ‘#'.
All'interno della struttura `<map>...</map>`, si usa il tag `<area>` per specificare le regioni che saranno cliccabili. Questo tag ha un'attributo shape che indica la forma dell'area (sono possibili tre alternative: "circle", "rect" e "poly") e l'attributo coords che specifica i punti sull'immagine per delimitare l'area. I punti sono espressi come coppie di numeri interi considerando l'immagine com un piano con il punto 0,0 nell'angolo in alto a sinstra.
Il formato dei punti nell'attributo coords di un tag `<area>` dipende dallo specifico shape
Per ogni elemento `<area>` si deve poi specificare con l'attributo href l'elemento di destinazione (si vedano le regole del tag `<a>` viste sopra). È una buona norma favorire l'accessibilità fornendo anche un testo alternativo nell'attributo alt.
Le figure 9.1 e 9.2 mostrano un esempio di un'immagine di una cartina dell'Europa in cui la regione corrispondente all'Italia è resa cliccabile e si collega ipertestualmente ad un altro documento HTML.
<map name="map">
<area shape="poly" coords="308,629,301,585,303,584,380,560,400,568,407,593,380,599,450,699,493,701,455,758,445,784,392,768,437,749,440,714,356,653,308,629" href="italia_mappa.html" alt="Area dell'Italia">
</map>
Figura 9.1 Esempio di mappa interattiva costruita sul un'immagine
Figura 9.2 L'immagine della mappa usata nell'esempio di figura 9.1 e i punti (non visibili nella pagina web) usati per tracciare il contorno dell'area della mappa da usare come anchor. |
Cascading Style Sheet (CSS) è un linguaggio di specifiche per la formattazione grafica. È stato inventanto più o meno contestualmente all'HTML da un collega di Tim Berners-Lee, Håkon Wium Lie, sempre al CERN (Munro, 2024) per permettere agli autori di documenti HTML un minimo di personalizzazione nelle visualizzazioni dei documenti (Bos, 2016). È però solo nel 2016, con lo standard HTML4, che si finalizza l'idea di una chiara separazione tra la definizione della struttura dei documenti (in HTML) e la specificazione delle modalità di visualizzazione o, in altre parole, lo stile (in CSS).
Un concetto importante già presente nelle prima versioni di CSS è la nozione di "progressività" nella definizione degli stili: questi sono raggruppati in fogli (sheet) che possono essere specificati in sequenza (cacading) e in caso di conflito (uno stile dichiarato più volte) viene applicata solo l'ultima definizione. Questa regola permette di poter prima definire parametri generali e poi concretizzarli e adattarli ad uno singolo dispositivo, semplicemente riscrivendo quando già specificato precedentemente. In questo modo, la responsabilità di come visualizzare un documento è in parte sulle spalle dell'autore del documento e in parte sulle spalle del browser: nel caso del web, questa caratteristica è importante perché l'autore può non essere sempre consapevole di tutte le caratteristiche dei vari dispositivi su cui il documento sarà visualizzato.
A differenza di HTML, CSS non è un linguaggio di markup, nel senso che gli stili non vengono applicati direttamente sul testo in formato di annotazione ma è un linguaggio di specifiche che si applicano ai tag HTML e alle loro istanze individuali (cioè ad una specifica annotazione con un tag di un certo tipo all'interno del documento) e a gruppi di istanze (che in CSS vengoni definiti "classi").
La struttura tipica delle specifiche di CSS è rappresentata in figura 10.1. Il tag da definire si trova all'inizio di una riga e le proprietà da modificare (sovrascrivendo i valori precedenti) vengono messe all'interno di parentesi graffe `{...}`. Ogni tag ha un insieme predefinito di proprietà (le principali sono descritte nel seguito). Ogni proprietà che si vuole modificare viene elencata separatamente seguita dal nuovo valore della proprietà (anche l'insieme dei valori per ogni proprietà è definito a priori). Le coppie proprietà (property) e valore (value) sono separate dal carattere ‘:' e terminate dal carattere ‘;'.
Figura 10.1 Schema di base della specificazione di un tag in CSS |
I commenti in CSS si indicano con l'annotazione `/* ... */`.
Gli stili possono essere collegati ad un documento HTML in tre diversi modi: inline, internal e external.
Inline styles: sono specifiche di stile applicate direttamente nel tag tramite l'attributo style (nota: la sintassi è quella della figura 10.1 ma senza la menzione al tag né le parentesi graffe). Lo stile si applica all'istanza del tag in cui lo stile è riportato (e non a tutti i tag dello stesso tipo). Un esempio in figura 10.2, in questo caso la porzione di testo "Hello World!" sarà scritta in colore rosso e avrà una dimensione di 24 pixel, il resto delle proprietà le prenderà dagli stili del titolo di primo livello, le altre porzioni di testo annotate con questo tag useranno, se non ulteriormente specificato, le proprietà di default del colore e della grandezza.
<h1 style="color: red; font-size: 24px;">Hello, World!</h1>
Figura 10.1 Esempio di uso di inline styles
Internal styles: le specifiche di stile sono incluse tra i tag
`<style> ...</style>` nella sezione head. In questo caso, gli stili di definiti per un tag vengono applicate per tutti i tag di quel tipo nel documento (tranne se sono sovrascritte come inline style). Si veda figura 10.2.
<head>
...
<style>
h1 {
color: red;
font-size: 24px;
}
...
</style>
Figura 10.2 Esempio di uso di internal styles
External styles: sono definiti in un file esterno (di solito con estensione .css) e vengono caricati nel documento HTML usando il tag self-closing `<link>` l'URL del file nell'attributo href (come per le àncore nel tag `<a>` e `<area>`) e che si tratta di un link ad un CSS nell'attributo rel
. Si veda la figura 10.3.
<!DOCTYPE html>
<html>
<head>
...
<link rel="stylesheet" href="styles.css">
...
</head>
Figura 10.3 Esempio di uso di internal styles
In riferimento alla figura 10.3, il file "styles.css" (che in questo caso dovrà trovarsi nella stessa directory del file html), avrà lo stesso formato introdotto sopra per specificare gli stili ai tag (ma senza essere i tag `<style> ... </style>`. Si veda figura 10.4 e relativi file di esempi.
h1 {
color: red;
font-size: 24px;
}
Figura 10.3 Esempio di file CSS da inserire come link in documenti HTML
Il termine cascading (che si potrebbe tradurre come "a cascata") si riferisce alla natura gerarchica del processo di applicazione delle regole di stile.
La gerarchia delle priorità funziona con tre principi:
In CSS, un selettore è uno schema che permette di identificare l'elemento (o gli elementi) all'interno di un documento HTML a cui applicare una regola di stile.
I selettori sono di vari tipi, i principali, descritti qui sotto sono i seguenti: element selector, universal selector, class selector,ID selector, attribute selector, descendant selector, child selector, adjacent sibling selector, pseudo-classes e pseudo-elements selector.
È il selettore più semplice che abbiamo visto anche nel capitolo precedente. Consiste nel nome di un tag seguito dall'elenco delle coppie proprietà e valore divise dal carattere ‘:' e terminate dal carattere ‘;' Se a più tag si vogliono applicare gli stessi stili, si possono separare da virgole. (figura 11.1).
h1 {color: red; }
h1, h2, h3 {color: red;}
Figura 11.1 Esempio Elemental selector
Gli stili si applicano a tutte le istanze di tag specificati all'interno del documento in cui lo stile è caricato.
È un caso particolare del precedente e si riferisce a tutti i tag del documento. Si specifica con il carattere ‘*'.
* {
color: black;
text-decoration: underline red;
}
Figura 11.2. Esempio universal selector
È una buona pratica non usare il selettore universale ma applicare gli stili ai tag più specifici perché il principio dell'ereditarietà spesso sfugge di mano (si veda l'esempio in https://jsfiddle.net/massimo_zancanaro/utw9smjx/57/).
Ogni tag HTML permette l'uso dell'attributo class per identificare un gruppo di istanze tag a cui assegnare delle proprietà specifiche. Il valore dell'attributo è una stringa che segue le stesse regole degli identificatori (si veda sopra capitolo 9). Nell'attributo class si possono elencare più identificativi separati da spazi e la specifica istanza risulterà appartenere a tutti i gruppi/classi elencati.
In CSS, poi si possono definire gli stili per le diverse classi e, combinando il class selector con l'elemental selector si possono restringere alle sole istanze che appartengono alla classe ma del particolare tag. Nel CSS, per identificare una classe si usa il nome prefisso con il carattere ‘.' (si veda figura 11.3 e https://jsfiddle.net/massimo_zancanaro/osky9e3L/3/).
.classe-1 {
color: yellow;
}
p.classe-1 {
color: red
}
Figura 11.3. Esempio class selector per la classe classe-1 applicato a tutte le istanze e a tutte le istanze del tag p
HTML permette di aggiungere l'attributo id ad ogni tag (come abbiamo già visto per il tag `<map>` nel capitolo 9) e questo permette, tra le altre cose, di applicare stili appropriati ad ogni singola istanza di tag. Nel CSS ci si riferisce alla specifica istanza usando il nome dell'ID prefisso dal carattere ‘#' (figura 11.4).
#id_esempio {
color: yellow;
}
Figura 11.4. Esempio id selector
Permette di selezionare solo le istanze di tag in un documento che hanno un determinato attributo. Sì può specificare la mera presenza dell'attributo (cioè indipendentemente dal valore assegnato) oppure l'attributo con un valore specifico.
Nell'esempio riportato in figura 11.5, evidenzia i link che si apriranno in un‘altra pagina, cioè quelle con l'attributo target con valore "_blank" con uno sfondo blu scuro, caratteri in grassetto e di colore bianco; la regola successiva invece specifica di usare caratteri con colore rosse per i link che hanno l'attributo alt , indipendentemente dal valore, cioè dal testo usato come alternativa all'immagine. Si può vedere un esempio di applicazione qui: https://jsfiddle.net/massimo_zancanaro/tpd7naxc/17/.
a[target="_blank"] {
color: white;
background: darkblue;
font-weight: bold;
}
a[alt] {
color: red;
}
Figura 11.5. Esempio attribute selector: notare che l'ordine in cui le regole sono scritte è importante, se le si inverte, quella con l'attribute selector [alt] non viene applicata (ma si veda più avanti)
È importante osservare in questo caso l'effetto del principio dell'ordine di apparizione nelle regole: se si inverte l'ordine, i link con l'attributo alt e target a _blank non risulteranno più di colore rosso. In realtà, saranno prima stati resi con colore rosso per effetto della regola di stile per a[alt] ma poi riscritti in bianco per effetto dell'altra regola. Si può agire sulla priorità delle regole, anche senza invertire l'ordine, usando la direttiva !important.
a[alt] {
color: red!important;
}
a[target="_blank"] {
color: white;
background: darkblue;
font-weight: bold;
}
Figura 11.6. Esempio attribute selector: anche con l'ordine invertito, si può dare priorità al colore specificato nella regola meno recente, usando la direttiva !important
In HTML, alcuni tag possono avere diversi stati: ad esempio, un link può essere già stato visitato (visited) oppure no (link). Le pseudo-class sono dei selettori che permettono di applicare gli stili a determinati stati. Sono prefisse da ‘:' e le più frequenti sono:
Se si usano tutti e quattro sul tag `<a>` per controllare la visualizzazione dei link, è importante ricordarsi che a:hover deve essere messo dopo a:link e a:active dopo a:hover.
Si può vedere un esempio in https://jsfiddle.net/massimo_zancanaro/jfmena4d/24/
Un altro insieme di pseudo-class permettono di riferirsi alle istanze di tag a seconda dell'ordine in cui appaiono nel documento:
I pseudo-element permettono di specificare determinate parti di un'istanza di un tag, Ad esempio, l'aggiungere contenuto decorativo prima o dopo un tag senza dover modificare il testo o specificare la dimensione della prima lettera. Un uso frequente è quello di poter definire come viene visualizzata la selezione di testo da parte dell'utente.
I pseudo-element sono prefissi da ‘::' e ovviamente possono essere usati in combinazione ai selettori descritti sopra. I più frequenti sono i seguenti:
Si può vedere un esempio in https://jsfiddle.net/massimo_zancanaro/85gb3ezd/latest/
Questi tre selettori sono un po' più complicati e vengono usati per gestire visualizzazioni complesse. In genere, si possono sostituire con un uso appropriato di class selector e id selector. Il vantaggio di usare questi e che non è richiesto modificare il documento HTML aggiungendo identificatori.
Si può vedere un esempio in https://jsfiddle.net/massimo_zancanaro/4se0kLuo/latest/
In questo capitolo vengono illustrate le proprietà più usate di CSS e l'uso dei colori. Per una lista completa, si può vedere qui: https://www.w3.org/TR/css-2023/#properties
In CSS, è spesso necessario esprimere misure di lunghezza per gli aspetti legati all'impaginazione e alle dimensioni dei caratteri. Ci sono due tipo di misure di lunghezza: le misure assolute e le misure relative.
Le misure assolute comprendono i centimetri (cm), i millimetri (mm), i pollici (in), i pixel (px) , i punti (pt) che sono una misura tipica della tipografia tradizionale ed equivalgono ad 1/72 di pollice e i picas (pc) che sono 12 punti. Le misure assolute sono utili quando si vuole avere un'alta precisione e quando si prepara un documento per la stampa ma si adattano male ai diversi dispositivi portando a problemi di usabilità e di accessibilità.
Le misure relative sono in generale da preferirsi quando si lavoro sul web e comprendono la percentuale (%) dell'elemento che contiene quello in cui si specificano le misure, la percentuale del viewport (cioè della finestra in cui è visualizzato il documento) in orizzontale (viewport width, vw) e in verticale (viewport height, vh), e em è la proporzione con l'altezza del carattere dell'elemento (ce ne sono altre ma meno comuni).
I colori si specificano con le proprietà color e background-color presenti nella maggior parte dei tag.
CSS usa il modello modello di colore RGB e i singoli colori si possono specificare usando i codici esadecimali per la percentuale di rosso, verde e blu (ad esempio #ff0000 corrisponde al rosso, #00ff00 al verde e così via), oppure specificando la funzione rgb(r,g,b) con r,g,b valori interi in decimale tra 0 e 255 per i tre colori (esiste anche la funzione rgba(r,g,b,a) dove il quarto valore corrisponde all'opacità (alpha) espressa come percentuale tra 0% (colore totalmente trasparente) e 100% (totalmente opaco). Si possono anche specificare i colori usando le coordinate cilindriche HSL usando la funzione hsl(h,s,l) dove il primo valore è la tinta (hue) e si esprime come intero decimale tra 0 e 360 (0 equivale al rosso, 120 al verde e 240 al blu), il secondo è una percentuale che definisce la saturazione (da grigio a colore pieno) e il terzo è una percentuale che definisce la quantità di luce (da nero a bianco). Anche per HSL esiste la funzione che include anche l'opacità hsla.
Nelle specifiche di CSS vengono anche definiti 140 nomi dei colori più usati, tra cui red, green, yellow, blue, orange, e gli equivalenti più chiari lightred, lightgreen eccetera e più scuri darkred, darkgreen eccetera. Un elenco completo lo si può trovare in https://www.w3schools.com/colors/colors_names.asp
Le proprietà tipografiche sono quelle relative agli stili dei caratteri:
E quelle relative all'allineamento sulla riga:
Si veda un esempio qui: https://jsfiddle.net/massimo_zancanaro/y3o7esu0/latest/
L'idea di base della distinzione tra HTML e CSS è di separare la descrizione della struttura di un documento (fatta in HTML) dalla gestione della sua visualizzazione (definita in CSS). Finora, abbiamo visto che con CSS si possono definire stili specifici per rendere i caratteri sulle righe e le principali strutture HTML. Il problema maggiore per visualizzare i documenti però resta quello dell'impaginazione, cioè come gestire gli spazi e il posizionamento dei vari elementi nello spazio bidimensionale della pagina. Per le pagine web, c'è l'ulteriore complicazione che i dispositivi hanno dimensioni diverse e lo stesso documento potrebbe dover essere visualizzato in modi anche molto diversi. Il termine responsive design indica una serie di strategie e tecniche per definire nel modo più generale possibile (cioè in modo indipendente dalle proprietà degli specifici device) i vincoli della visualizzaione del documento.
Ogni tag HTML è reso graficamente come una scatola divisa in varie parti (box model) come modo illustrato in figura 13.1:
Alcuni esempi sono riportati in https://jsfiddle.net/massimo_zancanaro/sr7Lj0q9/latest
Figura 13.1. Visualizzazione del Box Model per gestire la resa grafica di ogni elemento HTML. |
È importante ricordare che la dimensione orizzontale di un elemento non è determinato dalle sola proprietà width che si applica al solo content ma dalla somma di questa più due volte le dimensioni del border e del padding di sinistra, le dimensioni del border e del padding a destra; in modo simile si calcola la dimensione verticale considerano la height del content più il top e il bottom di border e padding. Per calcolare inoltre la quantità totale di spazio occupato dall'elemento, bisogna considerare anche gli spazi in alto, in basso, a destra e a sinistra del margin.
In HTML (e quindi in CSS) ci sono due tipi principali di box per gli elementi, quelli che creano un blocco (block) che inizia sempre da una nuova riga e occupa tutto lo spazio disponibile e quelli che invece sono visualizzati all'interno di una riga (inline) e occupando solo lo spazio necessario (esiste anche la proprietà inline-block che visualizza l'elemento sulla riga ma permette di occupare internamento lo spazio specificato).
Gli elementi di tipo block sono `<div>`, `<p>`, `<li>`, ...mentre quelli inline sono `<span>`, `<a>`, `<img>`, ... La proprietà display è in genere predefinita ma la si può modificare per variare il comportamento di un elemento, ad esempio per avere liste puntate orizzontali invece che verticali (cambiando il display dell'elemento li da block a inline).
Oppure si può settare al valore none per eliminare l'elemento dalla visualizzazione: in questo caso, l'elemento non verrà visualizzato ma sarà comunque presente nel documento e quindi manipolabile da Javascript come si vedrà in seguito (si noti che tutti gli elementi HTML hanno anche la proprietà visibility che è predefinita a visible ma può essere messa a hidden per nascondere l'elemento: però display none è diverso dalla proprietà a hidden perché quest'ultima rende l'elemento non visibile ma occupa ancora lo spazio definito dal box model mentre display none rimuove l'elemento dalla visualizzazione e quindi lo spazio è disponibile per gli altri elementi). Si vedano alcuni esempi in
Il modello più semplice (ma meno efficace) da usare per controllare l'impaginazione è il modello predefinito e si basa sul principio di posizionare gli elementi dall'alto in basso e da sinistra a destra. Gli elementi con display di tipo block iniziano sempre a sinistra e occupano tutto lo spazio disponibile o richiesto (se è specificata la width e la height); gli elementi inline occupano lo spazio previsto in direzione destra. Il comportamento definito sopra è quello della modalità static che è la modalità di posizionamento predefinita. Però questa modalità può essere cambiata modificando la proprietà position influendo quindi su come gli elementi si dispongono nella pagina.
Mettendo la modalità relative per la proprietà position un elemento può essere disposto sempre seguendo l'ordine definito sopra ma considerando i vincoli specificati nelle proprietà top, right, bottom, left.
Con la modalità fixed un elemento può essere messo in una posizione fissa rispetto alla viewport considerando vincoli specificati nelle proprietà top, right, bottom, left.
La modalità absolute sistema un elemento in una posizione fissa considerando vincoli specificati nelle proprietà top, right, bottom, left ma rispetto all'elemento precedente invece che al viewport.
Infine, la modalità sticky combina relative e fixed: permette di spostare l'elemento finché non raggiunge la posizione specificata e poi lo blocca in quella posizione (questa modalità però non funziona in tutti i browser).
Un esempio in https://jsfiddle.net/massimo_zancanaro/z63revda/latest/
Il modello a griglia permette di definire una scacchiera di celle sullo schermo e posizionare i blocchi direttamente nelle celle.
Una griglia si costruisce attribuendo ad un elemento il valore grid (oppure inline-grid) alla proprietà display. Di solito, viene usato un tag `<div>` ma possono essere usati anche i nuovi tag HTML5.
Gli spazi tra le colonne e tra le righe della griglia possono essere adattati usando le proprietà column-gap row-gap (o oppure la proprietà gap che ha due parametri: lo spazio tra le colonne e quello tra le righe).
Usando poi le proprietà grid-row e grid-column negli elementi che vogliamo posizionare in una determinata riga e in una determinata colonna. Se vogliamo che un elemento occupi più di una riga o più di una colonna, lo si può specificare con le proprietà grid-row-start e grid-row-start (e le relative grid-column-start e grid-column-end).
Si veda nell'esempio https://jsfiddle.net/massimo_zancanaro/p6Lrsw1m/latest come due blocchi di testo possono essere posizionati in ordine inverso rispetto a come sono nel documento HTML specificando in quale celle devono trovarsi.
È il modello più recente e il più adatto per un responsive design efficace. È basato su un modello unidimensionale (invece che bidimensionale come il modello griglia). Spesso viene combinato con il modello a griglia: la griglia viene usata per posizionare gli elementi principali del documento (o della web app) mentre il modello flexbox viene usato per rendere responsive le sotto parti.
Il modello flexbox consiste in un elemento contenitore (detto flex container, che in genere è un `<div>`) e in diversi elementi (detti flex items) che devono essere posizionati all'interno del flex container. Il flex container viene definito settando il valore flex nella la proprietà display. Altre proprietà vengono definite in parte nel flex container e in parte nei flex items.
Figura 13.2. Visualizzazione del Box Model per gestire la resa grafica di ogni elemento HTML. |
Le proprietà del flex-container (oltre a display) sono le seguenti:
Le proprietà dei flex-item sono le seguenti:
Si vedano gli esempi: https://jsfiddle.net/massimo_zancanaro/eqaj9fv6/latest e https://jsfiddle.net/massimo_zancanaro/2cztnq4s/latest
I documenti HTML possono essere resi "dinamici" con l'uso di Javascript. Si possono cioè aggiungere, togliere e nascondere tag o contenuto testuale e anche modificare gli stili CSS dopo che un documento HTML è stato visualizzato e in base ad azioni (click, movimenti del mouse, ecc.) compiuti dall'utente.
Per poter agire su uno specifico documento HTML, il codice Javascript deve essere inserito nel documento usando il tag `<script>`. Questo tag può contenere all'interno il codice HTML o avere un riferimento ad un file esterno e può essere messo in qualunque posizione all'interno del documento. Il codice Javascript viene eseguito appena viene caricato.
Figura 14.1. Due modi di associare codice Javascript ad HTML (nota: il tag `<script>` può essere messo anche nella sezione body ma è buona norma inserirlo sempre nella sezione head) |
Quando uno script viene eseguito all'interno di un browser, ha accesso ad alcuni oggetti utili per interagire con la finestra del browser e con il documento HTML. L'oggetto principale è window che rappresentare il dominio globale (e si può anche non scrivere: ogni variabile e metodo senza una ulteriore specificazione farà riferimento al contesto di window).
Le principali proprietà dell'oggetto window sono:
Quando il browser carica un file HTML per visualizzare una pagina web, costruisce una struttura che di chiama DOM per Document Object Model. Si tratta di una struttura dati ad albero (si veda la voce di Wikipedia Tree Data Structure) in cui ogni nodo contiene un elemento del documento HTML. La struttura dati ha diversi metodi e proprietà per cercare e modificare gli elementi. Il DOM è un oggetto che si chiama document ed è accessibile come proprietà dell'oggetto window una volta che la pagina è stata caricata.
I metodi principali dell'oggetto document sono quelli che permettono di accedere agli elementi del DOM:
Il metodo getElementById() restituisce un oggetto di tipo HTMLElement che è associato all'elemento dell'HTML visualizzato nel browser e, se modificato, i cambiamenti vengono sincronizzati con la visualizzazione del documento. Le proprietà principali di HTMLElement sono:
L'esempio di Figura 14.2 illustra come da Javascript si può cambiare il documento visualizzato modificando il valore della proprietà textContent di un elemento.
Figura 14.2. L'esempio di manipolazione del DOM in Javascript per cambiare la visualizzazione di un documento HTML: in questo caso, il testo "??" viene sostituito dal numero "10". |
Per i metodi o le proprietà in cui viene restituito un elenco (ad esempio getElementsByClass o children), è importante notare che non si tratta di normali Array Javascript ma di una struttura diversa a cui è comunque possibile accedere usando gli indici e le parentesi quadrate oppure l'operatore of in un ciclo (ma non il metodo forEach).
Rispondere in modo dinamico alle azioni dell'utente quali click, movimenti di mouse ecc. significa cambiare in modo dinamico la struttura del DOM usando i metodi visti nella sezione precedente. È necessario però capire in che modo il programma Javascript può "sapere" quando l'utente ha fatto una certa azione (e dove, cioè su qualche elemento del DOM).
Per fare ciò, si utilizza un approccio chiamato event-driven che consiste nello scrivere delle funzioni dette listener per rispondere a degli eventi predefiniti. Gli eventi principali che i browser moderni mettono a disposizione sono i seguenti:
Gli eventi elencati sopra pertengono al DOM e ai suoi elementi: vengono cioè collegati, come vedremo più avanti, a specifici elementi dell'HTML. Altri eventi rilevanti sono però quelli che pertengono all'oggetto windows, in particolare:
Il metodo più semplice per gestire gli eventi è di definire associare un inline handler, cioè una funzione Javascript allo specifico tag HTML nel documento usando un attributo che ha lo stesso nome dell'evento con on premesso (onclick, ondblclick, ...).
La figura 14.3 illustra un esempio in cui la funzione cliccato() definita nella parte Javascript viene collegata ad un tag `<a>`. In questo modo, quando l'utente clicca sull'ancòra specificata, la funzione viene automaticamente chiamata. Da notare l'uso del tag `<a>` con l'attributo href uguale alla stringa "#": è uno stratagemma per avere il cursore in modalità puntatore senza avere un vero link. Lo stesso effetto si può comunque ottenere da CSS per ogni tipo di tag con la direttiva cursor: pointer.
Figura 14.3. Esempio di inline handler per l'evento click associato ad un tag `<a>`. |
L'uso degli inline handler è fortemente sconsigliato nella programmazione moderna perché rende il codice difficile da leggere e mescola aspetti di struttura con aspetti di controllo (violando quindi il principio di "separation of concerns"). Inoltre, si può definire solo una funzione per ogni evento per ogni elemento e non si possono gestire gli eventi dell'oggetto window. Infine, introduce fattori di rischio ed è inefficiente.
Il metodo migliore per gestire gli eventi è di associare la funzione di risposta ad un evento all'elemento del DOM (o all'oggetto window) usando il metodo addEventListener dell'oggetto (che può essere window, document oppure un HTMLElement). La figura 14.4 mostra l'esempio precedente realizzato con questo approccio: l'elemento da cliccare viene prima identificato nel DOM (in questo caso usando l'id "daCliccare" che deve essere specificato nell'HTML) e poi gli viene aggiunta la funzione listener.
Figura 14.4. Funzione listener associata all'elemento HTML tramite il metodo addEvent Listener (si veda figura 14.5 per l'esempio completo) |
Perché questo approccio funzioni però, è necessario che l'istruzione Javascript document.getElementByID venga eseguita solo dopo che il DOM è stato caricato: altrimenti, document ha il valore undefined e l'istruzione darà errore.
Per avere la certezza che l'oggetto document esista nel contesto di Javascript, si devono mettere tutte le istruzioni che lo utilizzano all'interno del listener dell'evento load dell'oggetto window. La figura 14.5 illustra l'esempio completo.
Figura 14.5. Funzione listener associata all'elemento HTML tramite il metodo addEvent Listener inserita nel listener dell'evento load. |
Un modo più elegante di associare i listener è l'uso delle arrow function di Javascript che permettono tra l'altro un uso più efficace delle variabili in quanto sono all'interno dello stesso scope. La figura 14.6 illustra l'esempio realizzato con le arrow function.
Figura 14.6. Esempio realizzato con le arrow function. |
Ci sono altre due strategie più semplici ma non sempre efficaci per assicurarsi che il DOM sia stato caricato e quindi omettere di gestire il documento all'interno del listener di load: (a) si può mettere lo script in fondo alla sezione body, e (b) si può usare la keyword defer come attributo del tag script per caricare lo script dopo il DOM. Il possibile problema con il primo approccio è che si assume che il documento venga caricato nell'ordine mentre è possibile che per aumentare l'efficienza, un browser possa dividere il caricamento in processi paralleli e asincroni. Il problema con il secondo approccio è che non tutti i browser riconoscono la keyword defer. In ogni caso, l'uso esteso dei listener e delle arrow function permette di fare pratica con l'approccio moderno alla programmazione.
Britannica, T. Editors of Encyclopaedia (2024, February 7). Markup language. Encyclopedia Britannica. https://www.britannica.com/technology/markup-language (disponibile a Marzo 2024)
Britannica, T. Editors of Encyclopaedia (2024, February 13). TCP/IP. Encyclopedia Britannica. https://www.britannica.com/technology/TCP-IP
Baran, P (1960) Reliable digital communication systems using unreliable networks repeater nodes https://www.rand.org/content/dam/rand/pubs/papers/2008/P1995.pdf
Cerf, V. & Kahn, R. (1974). A Protocol for Packet Network Intercommunication (PDF). IEEE Transactions on Communications. 22 (5): 637–648. doi:10.1109/TCOM.1974.1092259
CERN (2024) The birth of the Web https://home.cern/science/computing/birth-web
Conklin, Jeff (1987). Hypertext: An Introduction and Survey. Computer, 20(9), 17–41. https://doi.org/10.1109/MC.1987.1663693 (disponibile a Marzo 2024)
Hemmendinger, D. (2023, December 26). computer programming language. Encyclopedia Britannica. https://www.britannica.com/technology/computer-programming-language (disponibile a Marzo 2024)
Licklider, J. C.R., & Taylor, R. W. (1968). The computer as a communication device. Science and technology, 76(2), 1-3. https://moodlearchive.epfl.ch/2021-2022/pluginfile.php/2704820/mod_resource/content/3/LickliderApr68.pdf
Munro, A. (2024) CSS. Encyclopedia Britannica. https://www.britannica.com/technology/CSS-programming-language
Sperberg-McQueen C.M. & Burnard Lu (1999) Guidelines for Electronic Text Encoding and Interchange, TEI P3 Text Encoding Initiative, Chicago, Oxford https://www.tei-c.org/Vault/GL/P3/index.htm (disponibile a Marzo 2024)
WHATWG, HTML Living Standard https://html.spec.whatwg.org/ (disponibile a Marzo 2024)
W3School HTML Reference https://www.w3schools.com/tags/ (disponibile a Marzo 2024)
The Valley of Code https://thevalleyofcode.com/ (disponibile a Marzo 2024)
Wikipedia List of XML and HTML character entity references (disponibile a Marzo 2024)
Wikipedia Tree Data Structure (disponibile a Marzo 2024)