Szkielet dokumentu#
Składnia#
Składnia będzie bardzo podobna do już opisanej w kursie poświeconym językowi HTML 4.01 (link1, link2). Tworzę osobną stronę dla HTML5 ponieważ specyfikacja wprowadza szczegółowe opisy i kilka nowych pojęć.
Przestrzenie nazw#
W HTML5 dozwolone są następujące przestrzenie nazw (namespace):
- HTML namespace:
http://www.w3.org/1999/xhtml
- MathML namespace:
http://www.w3.org/1998/Math/MathML
- SVG namespace:
http://www.w3.org/2000/svg
- XLink namespace:
http://www.w3.org/1999/xlink
- XML namespace:
http://www.w3.org/XML/1998/namespace
- XMLNS namespace:
http://www.w3.org/2000/xmlns/
W składni HTML5 prefiksy przestrzeni nazw (namespace prefixes) oraz deklaracje przestrzeni nazw (namespace declarations) nie mają takiego samego efektu jak w przypadku XML. Dla przykładu, dwukropek nie ma specjalnego znaczenia w nazwach elementów HTML5.
Elementy#
W HTML5 wszystkie elementy podzielono na pięć odrębnych grup:
- Void elements:
area
,base
,br
,col
,command
,embed
,hr
,img
,input
,keygen
,link
,meta
,param
,source
,track
,wbr
- Raw text elements:
script
,style
- RCDATA elements:
textarea
,title
- Foreign elements: elementy z przestrzeni nazw MathML oraz SVG
- Normal elements: wszystkie pozostałe dozwolone w HTML5
Tagi (znaczniki) są używane do określania początku oraz końca elementów w kodzie strony. Raw text, RCDATA oraz normal elements mają znacznik otwierający wskazujący gdzie się rozpoczynają, oraz znacznik zamykający wskazujący ich zakończenie. Znaczniki otwierające i zamykające w przypadku niektórych normal elements mogą zostać pomnięte (takie przypadki zostaną dokładnie opisane nieco później). Znaczniki których pominąć nie można należy koniecznie umieszczać w dokumencie.
Void elements mają tylko znacznik otwierający, umieszczanie znacznika zamykającego dla tego typu elementów nie jest konieczne (w poprzednich specyfikacjach określano je jako empty elements - elementy puste).
Foreign elements muszą mieć znacznik otwierający i zamykający, albo znacznik otwierający typu samozamykającego (self-closing), który w takim przypadku nie może mieć znacznika zamykającego.
Zawartość każdego elementu należy umieszczać pomiędzy znacznikiem otwierającym (który w pewnych przypadkach może być domyślnie wstawiany) i tuż przed znacznikiem zamykającym (który także może być domyślnie wstawiany w pewnych okolicznościach). Dokładna dozwolona zawartość każdego elementu zależy od jego modelu zawartości (content model) i zostanie omówiona w dalszych częściach kursu. Elementy nie mogą zawierać treści, na które nie zezwala ich model zawartości.
Oprócz ograniczeń dla zawartości wynikających z modelu zawartości, pięć typów elementów mają dodatkowe wymagania składniowe.
Void elements nie mogą mieć żadnej zawartości (ponieważ nie mają znacznika zamykającego, żadna treść nie może zostać umieszczona między tagiem otwierającym a zamykającym).
Raw text elements mogą zawierać tekst, ale ma on pewne ograniczenia.
RCDATA elements mogą zawierać tekst oraz odwołania znakowe (ale bez tzw. ambiguous ampersand). Istnieją również dodatkowe ograniczenia.
Foreign elements zaczynające się od samozamykających tagów nie mogą mieć żadnej zawartości (jest to oczywiste, nie ma znacznika zamykającego więc nie ma możliwości umieszczenia czegoś między znacznikiem otwierającym a zamykającym). Elementy które nie zaczynają się samozamykającym tagiem mogą zawierać tekst, odwołania znakowe, sekcje CDATA, inne elementy, komentarze. Dodatkowo tekst nie może zawierać znaku <
(U+003C LESS-THAN SIGN) lub ambiguous ampersand.
Należy mieć na uwadze, że składnia HTML5 nie wspiera deklaracji przestrzeni nazw, nawet dla foreign elements. Przeanalizujmy następujący przykład:
<p>
<svg>
<metadata>
<!-- niedozwolony zapis -->
<cdr:license xmlns:cdr="http://www.example.com/cdr/metadata" name="MIT"/>
</metadata>
</svg>
</p>
Najbardziej zagnieżdzony element cdr:license
znajduje się aktualnie w przestrzeni nazw SVG, podobnie jak atrybut xmlns:cdr
i nie wywołuje żadnego efektu (w przeciwieństwie do XML). W rzeczywistości, komentarz w powyższym przykładzie mówi, że fragment kodu w tym miejscu jest nieprawidłowy. Dzieje się tak dlatego, że specyfikacja SVG nie określa żadnych elementów nazwanych cdr:license
w przestrzeni nazw SVG. Nie możemy manipulować przestrzenią nazw, jest ona określana automatycznie przez przeglądarki.
Normal elements mogą zawierać tekst, odwołania znakowe, inne elementy oraz komentarze. Dodatkowo tekst nie może zawierać znaku <
(U+003C LESS-THAN SIGN) lub ambiguous ampersand. Niektóre elementy tego rodzaju mogą mieć kolejne ograniczenia, oprócz tych wynikających z dozwolonego modelu zawartości.
Znaczniki zawierają nazwę znacznika, która nadaje elementowi nazwę. Wszystkie elementy HTML5 mają nazwy składające się wyłącznie z cyfr ASCII, małych liter i wielkich liter ASCII. W przypadku stosowania składni HTML5 wielkość znaków w nazwach znaczników (nawet dla foreign elements) jest nieistotna. Można stosować dowolne kombinacje wielkich i małych liter.
Znaczniki otwierające#
Tagi otwierające muszą mieć następującą postać:
- Pierwszym znakiem tagu zamykającego musi być U+003C LESS-THAN SIGN (
<
). - Kilka kolejnych znaków tagu zamykającego musi być nazwą elementu.
- Jeśli występują atrybuty w kolejnym kroku, najpierw musi pojawić się jeden lub więcej znaków spacji.
- Następnie, tag otwierający może zawierać wiele atrybutów, o ściśle określonej składni. Atrybuty muszą być oddzielone od siebie jednym lub większą liczbą znaków spacji.
- Po atrybutach lub nazwie tagu (jeśli brak atrybutów) może pojawić się jeden lub więcej znaków spacji. (Po niektórych atrybutach musi pojawić się spacja)
- Następnie, jeśli element należy do grupy void elements lub foreign elements można zastosować pojedynczy znak U+002F SOLIDUS (
/
). Znak ten nie ma żadnego wpływu na void elements, ale w przypadku foreign elements oznacza tag samozamykający. - Na koniec, tag otwierający musi zostać zakończony znakiem U+003E GREATER-THAN SIGN (
>
).
Z tego algorytmu wynika kilka interesujących kwestii. Pierwsza jest taka, że w składni HTML5 elementy typu void (dawniej zwanych pustymi) możemy zamykać łańcuchem />
. Zapis taki nie robi niczego sensownego, ale pozostawiono go ze względu na sporą liczbę osób, które dawniej próbowały stosować XHTML, ale nie bardzo wiedziały jak to robić prawidłowo (idealna składnia była niewystarczająca). Jeśli ktoś preferuje składnię XML (XHTML), ewentualnie próbuje tworzyć dokumenty dwujęzyczne (HTML5/XHTML5) może stosować ukośnik dalej. Prosty przykład:
<hr />
<hr>
<img src="" alt="" />
<img src="" alt="">
Zwracam uwagę, że w przypadku HTML5 nie możemy powyższej konstrukcji zastosować do innych elementów. Przykładowo element span
musi składać się ze znacznika otwierającego i zamykającego, użycie samozamykającego znacznika jest niedopuszczalne (chociaż prawidłowe np. w XHTML5).
<p style="color:green">
<span>Dowolny tekst koloru zielonego</span>
<span style="color:red" /> <!-- Niedozwolona składnia HTML5 -->
Kolor tego fragmentu tekstu będzie zależny od trybu przetwarzania: HTML5 (kolor czerwony) lub XHTML5 (kolor zielony)
</p>
Samozamykające znaczniki, które faktycznie będą spełniały swoje zadanie (czyli zamknięcie elementu bez konieczności stosowania tagu zamykającego) mogą być stosowane w składni HTML5 jedynie w przypadku MathML lub SVG.
Znaczniki zamykające#
Tagi zamykające muszą mieć następującą postać:
- Pierwszym znakiem tagu zamykającego musi być U+003C LESS-THAN SIGN (
<
). - Drugim znakiem tagu zamykającego musi być U+002F (
/
). - Kilka kolejnych znaków tagu zamykającego musi być nazwą elementu.
- Po nazwie tagu może wystąpić jeden lub większa liczba znaków spacji.
- Na koniec, tag zamykający musi zostać zakończony znakiem U+003E GREATER-THAN SIGN (
>
).
Atrybuty#
Elementy posiadają atrybuty, które można umieszczać jedynie wewnątrz znacznika otwierającego.
Atrybut posiada nazwę oraz wartość. Nazwa atrybuty musi składać się z jednego lub większej liczby znaków takich jak znaki spacji, U+0000 (NULL), U+0022 QUOTATION MARK ("
), U+0027 APOSTROPHE ('
), U+003E GREATER-THAN SIGN (>
), U+002F (/
) oraz U+003D (=
), znaków kontrolnych, a także innych znaków, które nie zostały zdefiniowane w Unikodzie. W przypadku stosowania składni HTML5 wielkość znaków w nazwach atrybutów (nawet dla foreign elements) jest nieistotna. Można stosować dowolne kombinacje wielkich i małych liter.
Wartością atrybutu jest mieszanka tekstu oraz odwołań znakowych, z zastrzeżeniem, że tekst nie może zawierać ambiguous ampersand.
Atrybuty można wprowadzać na cztery różne sposoby:
- Składnia pustego atrybutu (Empty attribute syntax)
Wystarczy sama nazwa atrybutu. Domyślną wartością jest pusty łańcuch znakowy. Przykład:
<input disabled>
Jeśli po atrybucie tego typu będzie występował kolejny atrybut, należy umieścić między nimi znak spacji.
- Składnia wartości atrybutu bez cudzysłowów (Unquoted attribute value syntax)
Po nazwie atrybutu występuje zero lub więcej znaków spacji, następnie znak U+003D EQUALS SIGN (
=
), następnie zero lub więcej znaków spacji, następnie wartość atrybutu. Wartość atrybutu musi spełniać wymagania opisane nieco wcześniej, oraz nie może zawierać bezpośrednich znaków spacji, U+0022 QUOTATION MARK ("
), U+0027 APOSTROPHE ('
), U+003D EQUALS SIGN (=
), U+003C LESS-THAN SIGN (<
), U+003E GREATER-THAN SIGN (>
), U+0060 (`
), a także nie może być pustym łańcuchem. Przykład:<input value=yes>
Jeśli po atrybucie tego typu będzie występował kolejny atrybut lub opcjonalny znak U+002F (
/
) dozwolony w 6 kroku dla znacznika otwierającego, wówczas należy umieścić między nimi znak spacji. Czyli następujący zapis dla void elements lub foreign elements będzie prawidłowy:<img src=adres alt=opis />
- Składnia wartości atrybutu w pojedynczym cudzysłowie (Single-quoted attribute value syntax)
Po nazwie atrybutu występuje zero lub więcej znaków spacji, następnie znak U+003D EQUALS SIGN (
=
), następnie zero lub więcej znaków spacji, następnie znak U+0027 APOSTROPHE ('
), następnie wartość atrybutu. Wartość atrybutu musi spełniać wymagania opisane nieco wcześniej, oraz nie może zawierać bezpośrednich znaków U+0027 APOSTROPHE ('
) - jeśli koniecznie chcemy wstawić taki znak należy użyć odwołań znakowych. Na koniec należy wstawić drugi znak U+0027 APOSTROPHE ('
). Przykład:<input type='checkbox'>
Jeśli po atrybucie tego typu będzie występował kolejny atrybut, należy umieścić między nimi znak spacji. Należy zauważyć, że w tym wypadku poniższy zapis będzie prawidłowy:
<img src='adres' alt='opis'/>
Czyli znak spacji przed znakiem (
/
) nie jest konieczny. Ta sama uwaga będzie dotyczyła kolejnego przypadku. - Składnia wartości atrybutu w podwójnym cudzysłowie (Double-quoted attribute value syntax)
Po nazwie atrybutu występuje zero lub więcej znaków spacji, następnie znak U+003D EQUALS SIGN (
=
), następnie zero lub więcej znaków spacji, następnie znak U+0022 QUOTATION MARK ("
), następnie wartość atrybutu. Wartość atrybutu musi spełniać wymagania opisane nieco wcześniej, oraz nie może zawierać bezpośrednich znaków U+0022 QUOTATION MARK ("
) - jeśli koniecznie chcemy wstawić taki znak należy użyć odwołań znakowych. Na koniec należy wstawić drugi znak U+0022 QUOTATION MARK ("
). Przykład:<input name="be evil">
Nigdy nie mogą wystąpić dwa atrybuty o identycznych nazwach (wielkość znaków w przypadku składni HTML5 bez znaczenia) w tym samym znaczniku otwierającym.
Kiedy foreign element ma jedną z atrybutowych przestrzeni nazw podanych przez local name oraz namespace (pierwsza i druga komórka tego samego wiersza w poniższej tabeli), musi to zostać zapisane przy użyciu nazwy umieszczonej w trzeciej komórce tego samego wiersza.
Local name | Namespace | Attribute name |
---|---|---|
actuate | XLink namespace | xlink:actuate |
arcrole | XLink namespace | xlink:arcrole |
href | XLink namespace | xlink:href |
role | XLink namespace | xlink:role |
show | XLink namespace | xlink:show |
title | XLink namespace | xlink:title |
type | XLink namespace | xlink:type |
base | XML namespace | xml:base |
lang | XML namespace | xml:lang |
space | XML namespace | xml:space |
xmlns | XMLNS namespace | xmlns |
xlink | XMLNS namespace | xmlns:xlink |
Żadnna inna atrybutowa przestrzeń nazw jest niedopuszczalny w składni HTML5.
Znaczniki opcjonalne#
W pewnych okolicznościach niektóre znaczniki można pominąć. Specyfikacja HTML5 ściśle definiuje takie przypadki.
Pominięcie znacznika otwierającego dla elementu nie oznacza, że element jest nieobecny; zostanie wstawiony domyślnie. Dla przykładu, dokument HTML5 zawsze posiada główny element html
, nawet jeśli łańcuch znaków <html>
nie pojawia się w naszym kodzie. Trzeba o tym pamiętać, szczególnie przy manipulowaniu drzewem DOM, ponieważ czasami mogą występować węzły, których nigdy nie umieściliśmy samodzielnie w kodzie (np. tbody
w table
).
Znacznik otwierający element html
można pominąć jeśli pierwszą rzeczą wewnątrz elementu html
nie jest komentarz.
Znacznik zamykający element html
można pominąć jeśli bezpośrednio po elemencie html
nie ma komentarza.
Znacznik otwierający element head
można pominąć jeśli element jest pusty, albo jeśli pierwszą rzeczą wewnątrz elementu head
jest inny element.
Znacznik zamykający element head
można pominąć jeśli bezpośrednio po elemencie head
nie ma znaku spacji lub komentarza.
Znacznik otwierający element body
można pominąć jeśli element jest pusty, lub pierwszą rzeczą wewnątrz elementu body
nie jest znak spacji lub komentarz, z wykluczeniem, że pierwszą rzeczą wewnątrz elementu body
jest element script
lub style
.
Znacznik zamykający element body
można pominąć jeśli bezpośrednio po elemencie body
nie ma komentarza.
Znacznik zamykający element li
można pominąć jeśli bezpośrednio po elemencie li
występuje inny element li
, lub jeśli nie ma innej zawartości w elemencie nadrzędnym.
Znacznik zamykający element dt
można pominąć jeśli bezpośrednio po elemencie dt
występuje inny element dt
lub dd
.
Znacznik zamykający element dd
można pominąć jeśli bezpośrednio po elemencie dd
występuje inny element dd
lub dt
, lub jeśli nie ma innej zawartości w elemencie nadrzędnym.
Znacznik zamykający element p
można pominąć jeśli bezpośrednio po elemencie p
występuje inny element address
, article
, aside
, blockquote
, dir
, div
, dl
, fieldset
, footer
, form
, h1
, h2
, h3
, h4
, h5
, h6
, header
, hgroup
, hr
, menu
, nav
, ol
, p
, pre
, section
, table
lub ul
, lub jeśli nie ma innej zawartości w elemencie nadrzędnym i elementem nadrzędnym nie jest element a
.
Znacznik zamykający element rt
można pominąć jeśli bezpośrednio po elemencie rt
występuje inny element rt
lub rp
, lub jeśli nie ma innej zawartości w elemencie nadrzędnym.
Znacznik zamykający element rp
można pominąć jeśli bezpośrednio po elemencie rp
występuje inny element rt
lub rp
, lub jeśli nie ma innej zawartości w elemencie nadrzędnym.
Znacznik zamykający element optgroup
można pominąć jeśli bezpośrednio po elemencie optgroup
występuje inny element optgroup
, lub jeśli nie ma innej zawartości w elemencie nadrzędnym.
Znacznik zamykający element option
można pominąć jeśli bezpośrednio po elemencie option
występuje inny element option
lub optgroup
, lub jeśli nie ma innej zawartości w elemencie nadrzędnym.
Znacznik otwierający element colgroup
można pominąć jeśli pierwszą rzeczą wewnątrz elementu colgroup
jest element col
, i jeśli element nie jest bezpośrednio poprzedzony innym elementem colgroup
, którego znacznik zamykający został pominięty. (Nie może zostać pominięty jeśli element jest pusty).
Znacznik zamykający element colgroup
można pominąć jeśli bezpośrednio po elemencie colgroup
nie ma znaku spacji lub komentarza.
Znacznik zamykający element thead
można pominąć jeśli bezpośrednio po elemencie thead
występuje inny element tbody
lub tfoot
.
Znacznik otwierający element tbody
można pominąć jeśli pierwszą rzeczą wewnątrz elementu tbody
jest element tr
, i jeśli element nie jest bezpośrednio poprzedzony innym elementem tbody
, thead
lub tfoot
, którego znacznik zamykający został pominięty. (Nie może zostać pominięty jeśli element jest pusty).
Znacznik zamykający element tbody
można pominąć jeśli bezpośrednio po elemencie tbody
występuje inny element tbody
lub tfoot
, lub jeśli nie ma innej zawartości w elemencie nadrzędnym.
Znacznik zamykający element tfoot
można pominąć jeśli bezpośrednio po elemencie tfoot
występuje inny element tbody
, lub jeśli nie ma innej zawartości w elemencie nadrzędnym.
Znacznik zamykający element tr
można pominąć jeśli bezpośrednio po elemencie tr
występuje inny element tr
, lub jeśli nie ma innej zawartości w elemencie nadrzędnym.
Znacznik zamykający element td
można pominąć jeśli bezpośrednio po elemencie td
występuje inny element td
lub th
, lub jeśli nie ma innej zawartości w elemencie nadrzędnym.
Znacznik zamykający element th
można pominąć jeśli bezpośrednio po elemencie th
występuje inny element td
lub th
, lub jeśli nie ma innej zawartości w elemencie nadrzędnym.
Znacznik otwierający nigdy nie może zostać pominięty jeśli zawiera atrybuty.
Reguły dotyczące stosowania opcjonalnych tagów w HTML5 są nieco zawiłe, dlatego lepiej nie polegać na tym mechanizmie. Proponuję zawsze stosować znaczniki otwierające i zamykające (oczywiśćie kiedy są dozwolone). Świadome pomijanie niektórych tagów (nawet jeśli jest poprawne) utrudnia analizowanie kodu przez osoby trzecie, które nie opanowały wszystkich zawiłości składni HTML5 do perfekcji.
Ograniczenia modelu zawartości#
Ze względów historycznych, niektóre elementy mają dodatkowe ograniczenia, poza ograniczeniami określanymi przez ich model zawartości.
Element table
nie może zawierać elementów tr
, chociaż z technicznego punktu widzenia elementy te są dozwolone wewnątrz elementów table
według zdefiniowanego modelu zawartości opisanego w specyfikacji. Jeśli element tr
jest umieszczony wewnątrz table
w kodzie strony, to w rzeczywistości automatycznie wprowadzony zostanie przed nim znacznik otwierający tbody
.
Pojedynczy znak nowej linii może zostać umieszczony bezpośrednio po znaczniku otwierającym element pre
lub textarea
. Nie wpływa to na przetworzenie elementu. Obydwie poniższe deklarację będą równoważne:
<pre>Hello</pre>
<pre>
Hello</pre>
Ograniczenia modelu zawartości dla elementów raw text oraz RCDATA#
Tekst w elementach typu raw text oraz RCDATA nie może zawierać żadnych wystąpień znaków </
(U+003C LESS-THAN SIGN, U+002F SOLIDUS), następnie znaków dopasowanych do nazwy znacznika (wielkość znaków bez znaczenia), następnie jednego ze znaków U+0009 (tabulator), U+000A (LF), U+000C (FF), U+000D (CR), U+0020 (spacja), U+003E (>
) lub U+002F (/
).
Będzie to szczególnie widoczne w przypadku skryptów osadzonych bezpośrednio w kodzie HTML5. Sposób obejścia problemu wyjaśniłem w kursie HTML 4.01 (dział "DTD - Typy danych w DTD").
Tekst#
Tekst jest dozwolony wewnątrz elementów, wartości atrybutów oraz komentarzy. Czasami wprowadzane są dodatkowe ograniczenia co do zawartości samego tekstu lub miejsca jego umieszczenia.
Nowa linia#
W HTML5 nowa linia może być reprezentowana za pomocą znaków U+000D (CR), U+000A (LF) lub parą znaków w dokładnie takiej kolejności: U+000D (CR), U+000A (LF).
Kiedy odwołania znakowe (character references) są dozwolone, odwołanie znakowe dla znaku U+000A (LF) - ale nie dla znaku U+000D (CR) - również stanowi nową linię.
Odwołania znakowe#
W pewnych przypadkach tekst może być wymieszany razem z odwołaniami znakowymi. Można je używać w celu zastąpienia pewnych znaków zastrzeżonych dla samej składni języka HTML5, przez co nie mogą wystąpić w jawnej postaci bezpośrednio w kodzie. Całe zagadnienie omówiłem dokładnie w porzednim kursie HTML 4.01 (dział "Zestawy znaków - Encje").
W specyfikacji HTML5 wprowadzono pojęcie ambiguous ampersand. Są to encje nazwane, które nie pasują do żadnej nazwy określonej w nowym języku HTML5.
Sekcje CDATA#
Jest to termin pochodzący z XML (a w konsekwencji także XHTML). W normalnych okolicznościach sekcje CDATA były zabronione w dokumentach HTML, aczkolwiek w nowym języku HTML5 możemy bezpośrednio osadzać języki MathML oraz SVG. Właśnie w ich przypadkach (czyli dla zawartości typu foreign content) bezpośrednie stosowanie sekcji CDATA jest dozwolone.
Sekcje CDATA muszą składać się z elementów w następującej kolejności:
- Łańcuch znaków
"<![CDATA["
- Opcjonalny tekst, z dodatkowym zastrzeżeniem, że nie może zawierać znaków
"]]>"
- Łańcuch znaków
"]]>"
Prosty przykład, w którym sekcja CDATA zostanie użyta na wartość elementu ms
:
<p>Możesz dodać tekst do liczby, ale to zwróci liczbę typu tekstowego:</p>
<math>
<ms><![CDATA[x<y]]></ms>
<mo>+</mo>
<mn>3</mn>
<mo>=</mo>
<ms><![CDATA[x<y3]]></ms>
</math>
Czyli sekcje CDATA umożliwiają jawne wprowadzenie zastrzeżonych znaków w przypadku XML (XHTML5), a także w pewnych okolicznościach dla HTML5 (dla SVG i MathML). Ich zawartość jest interpretowana jako surowy tekst.
Prawdę mówiąc CDATA może być użyta dla skryptów i stylów osadzonych w dokumentach HTML5, ale trzeba zastosować odpowiedni trick z komentarzami:
<!-- Dla skryptów JS -->
<script type="text/javascript"></script>
<!-- Dla stylów CSS-->
<style type="text/css">
/*<![CDATA[*/
body {background-image: url("test.png?width=300&height=300")}
/*]]>*/
</style>
Dzięki temu parser HTML5 pominie składnię odpowiedzialną za CDATA, natomiast parser XML weźmie ją pod uwagę. Technika taka przydaje się do tworzenia dwujęzycznych dokumentów HTML5 i XHTML5 (tzw. polyglot) . Najlepiej jednak stosować zewnętrzne pliki JS i CSS, wówczas problem ze stosowaniem znaków zastrzeżonych rozwiązuje się sam.
Komentarze#
Komentarz musi zaczynać się sekwencją czterech znaków <!--
(U+003C LESS-THAN SIGN, U+0021 EXCLAMATION MARK, U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS). Po tej sekwencji komentarz może zawierać tekst, z dodatkowym zastrzeżeniem, że tekst nie może zaczynać się od pojedynczego znaku >
(U+003E GREATER-THAN SIGN), ani znaku -
(U+002D) po którym następuje znak >
(U+003E GREATER-THAN SIGN), ani zawierać dwóch kolejnych znaków --
(U+002D HYPHEN-MINUS), ani kończyć znakiem -
(U+002D). Wreszcie, komentarz musi być zakończony przez sekwencję trzech znaków -->
(U+002D HYPHEN-MINUS, U+002D HYPHEN-MINUS, U+003E GREATER-THAN SIGN).
Bardzo dokładny opis komentarzy umieściłem w kursie HTML 4.01 (dział Formatowanie treści - Komentarze).
Znaki spacji#
Dla uściślenia, do znaków spacji (space characters) zalicza się U+0020 (spacja), U+0009 (tabulator), U+000A (LF), U+000C (FF) i U+000D (CR). Można powiedzieć, że w potocznym obiegu są to białe znaki, ale specyfikacja HTML5 wyraźnie wprowadza osobne terminy dla znaków spacji i białych znaków.
URLs#
Specyfikacja HTML5 poświęca sporo miejsca dla opisu adresów internetowych. Zawarto w niej szczegółowe informacje odnośnie budowy adresów, przetwarzania, adresów bazowych, rozwijania adresów bezwzględnych itd. W zasadzie bardziej przystępny materiał zamieściłem w kursie HTML 4.01 (dział "Odsyłacze - Adresy internetowe"). W celach uzupełniających warto jedynie przeanalizować interfejs manipulowania URL-ami oraz tabelkę z przykładami (jeśli dla kogoś temat dalej stanowi problem).
Gdzie zatem różnice?#
Jeśli chodzi o podstawową składnię w zasadzie wiele ich nie ma. Jedyna zauważalna zmiana to brak następujących możliwości wywodzących się z SGML-a, a opisywanych w specyfikacji HTML 4.01:
Są to abstrakcyjne terminy, gdyż instrukcje przetwarzania i skrócone tagi nigdy nie zostały zaimplementowane w aktualnych HTML-owych silnikach przeglądarek. Nie wiem, czy kiedykolwiek były one obsługiwane przez jakąkolwiek przeglądarkę internetową. Skrócone tagi są trudne w implementacji i mogą powodować problemy z możliwością pomijania tagów, która dla twórców przeglądarek jest istotniejsza.
Zgodność ze standardami#
Warto jeszcze wspomnieć o dwóch pojęciach, które bardzo często mogą pojawiać się w literaturze angielskiej. Chodzi o dokumenty określane jako well-formed oraz mal-formed. Pierwsze pojęcie oznacza dokumenty, które są zgodne z ogólnymi zasadami składniowymi dla danego języka, np. HTML spełnia reguły SGML, natomiast XHTML zachowuje składnię XML. Drugie pojęcie jest jego przeciwieństwem. Przykładowo, w HTML polecenie <b>test</b>
jest typu well-formed, natomiast <i><b>word</i>
już mal-formed. W XHTML elementy puste (nie posiadające nigdy zawartości) powinny być zamykane poprzez ukośnik na końcu znacznika otwierającego, np. <img />
, <br />
, <hr />
, ale w przypadku HTML nie trzeba tego robić. Dlatego konkretne określenie oraz wymogi je spełniające będą uzależnione od stosowanego języka.
Większość dokumentów HTML w Sieci będzie typu mal-formed. Przyczyna jest bardzo prosta, skoro przeglądarki samoczynnie korygują błędy programistów (z plików mal-formed zawsze robią well-formed), większość z nich nie stara się poznać stosowanej technologii w stopniu szerszym niż podstawowy. W dłuższej perspektywie czasu nie jest to dobre rozwiązanie, oprócz prawidłowego działania kodu (zgodnego z oczekiwaniem) powinien być on jeszcze łatwy w utrzymaniu. To drugie zadanie zdecydowanie lepiej osiągnąć mając do czynienia z dokumentami pisanymi w określony sposób.
Osobnym zagadnieniem będzie pojęcie walidacji (oraz walidatorów), które w przypadku (X)HTML będzie oznaczać zgodność ze specyfikacjami (wcześniej również z DTD). Dokumenty przechodzące walidację będą zawsze typu well-formed. Z racji tego, że w przeszłości walidacja utożsamiana była z DTD (a jak dobrze wiemy w HTML5 nie ma oficjalnego DTD), obecnie sugeruje się żeby narzędzia analizujące kod strony nazywać po prostu sprawdzaczami lub weryfikatorami zgodności (conformance checkers). Całą tą terminologią nie ma się co przejmować, w praktyce jest ona interpretowana nieco odmiennie przez każdego programistę.
Sporym wyzwaniem może być próba utrzymania stron w zgodności ze specyfikacjami. Narzędzia sprawdzające wciąż są w fazie rozwoju, często będą zwracać błędy tam, gdzie specyfikacja zezwala na dane polecenia. Autorzy takich narzędzi starają się wybiegać poza ramy specyfikacji, dlatego też błędami oznaczają pewne konstrukcje, które mogą powodować problemy np. w różnych przeglądarkach. Niezależnie od tego dalej warto weryfikować jakość tworzonego przez siebie kodu. Jest to jedna z lepszych metod nauki, mimo że początkowo wymaga nieco większego nakładu pracy.
Podsumowanie#
Widać wyraźnie, że składnia HTML5 pozwala naprawdę na bardzo wiele. Nie dość, że w większości jest identyczna z poprzednimi wersjami HTML-a, to na dodatek dopuszcza stosowanie pewnej części składni XHTML. Ciężko wyrokować czy jest to słuszne posunięcie, czy może spowodować zbyt dużą "rozwiązłość" ze strony programistów. Mnogość opcji nigdy nie będzie problemem jeśli pozostawiony zostanie swobodny wybór. Zawsze możemy ograniczyć składnię języka HTML5 do pewnego podzbioru i sumiennie ją stosować w swoich projektach. Niektórzy już teraz namawiają (warto przeczytać) do bardziej rygorystycznych wytycznych, do których sam się zaliczam.