Znaki specjalne w HTML

Riddle

Załóżmy, że chciałbyś wstawić na swoją stronę znak mniejszości lub większości - < lub >. Niestety, jak tylko wprowadzisz taki znak, zostanie on zinterpretowany jako otwierający lub zamykający tag HTML, dlatego że własnie znaków mniejszości i większości (czy jak kto woli, nawiasów trójkątnych) używa się do otwierania i zamykania tagów HTML.

<div class="container">
  Znak mniejszości to < yikes!
</div>

Ups! I co teraz? Nie możemy wyświetlić znaku większości, ponieważ interpreter pomyśli że chcieliśmy otworzyć tag HTML.

Uwaga! Dokładnie ten błąd w rozumieniu HTML wykorzystują atakujący storny internetowę, atak ten nazywa się XSS. Jeśli "bezmyślnie" wsadzimy tekst na stronę, to jego część (np znak mniejszości) może zostać błędnie zinterpretowany. Niepoprawnie skonstruowany tag, najwyżej sprawi że nasza strona brzydko się wyświetli. Umiejętny atakujący jednak tak stworzy wstawiony tekst, żeby takie mylne zinterpretowane HTML przyniosło więcej szkód (np dołączy skrypt <script> lub załaduje wrogi plik CSS, który może posłużyć za stronę phishingową, lub wstawi linki kierujące na strony scamowe).

Poprawne wyświetlanie znaków specjalnych.

W HTML istnieją znaki specjalne. Są to znaki, które mają specjalne znaczenie i nie są interpretowane dosłownie. Znaki które są interpretowane dosłownie to np litery i tekst.

W kodzie

<div>Welcome</div>

kod <div> oraz </div> są interpretowane jako kod HTML, natomiast tekst Welcome jest interpretowany dosłownie. Co to znaczy? Dosłownie, znaczy tożsamo: Litera W w kodzie, będzie wyświetlona jak "W" w wyrenderowanej stronie. Znak e w kodzie HTML, jak litera "e" na stronie itd. Innymi słowy, znaki interpretowane dosłownie pojawiają się na stronie dokładnie tak samo jak zostały wpisane do kodu. Nie wszystkie znaki są jednak interpretowane dosłownie. <div> nie wyświetli nam na stronie napisu "<div>", tylko stworzy nowy blok.

Jak więc wyświetlić < dosłownie? Istnieje do tego specjalny zapis w HTML. Każdy znak specjalny w HTML ma swój specjalny zapis, tak by na stronie można było wyświetlać dowolne znaki. Specjalnym zapisem < jest &lt; (less-than), a specjalnym zapisem znaku > jest &gt; (greater-than).

Żeby poprawnie wyświetlić znak mniejszości, posłużmy się takim kodem:

<div class="container">
  Znak mniejszości to &lt;
</div>

No dobrze! Świetnie! Widzimy na stronie tekst "Znak mniejszości to <", ale czy nie strzeliliśmy sobie teraz w stopę? Dlatego że dodaliśmy kolejny znak specjalny &, do dodania encji. Jak więc mam umieścić znak "&" na stronie, skoro on też będzie interpretowany specjalnie? To prawda, pozbyliśmy się specjalnego znaczenia znaku <, ale mamy teraz specjalne znaczenie znaku &.

To nic! Ponieważ znak & jest znakiem specjalnym w HTML, a ponieważ jest znakiem specjalnym to i ma on swoj specjalny zapis, dzięki któremu zobaczymy znak "&" dosłownie. Ten znak, nawiasem mówiąc & nazywa się ampersand. Jego zapisem specjalnym w HTML jest &amp;.

Hola hola, czy teraz żeby wyświetlić znak & muszę napisać &amp;? Dlaczego nie mogę po prostu wpisać & do kodu? Dlatego, że & w kodzie to znak specjalny HTML, a &amp; to zapis specjalny, ktory pozwoli nam wyświetlić "&" dosłownie.

Podsumowując:

  • żeby wyświetlić "Welcome", wpisz Welcome (dosłownie)
  • żeby wyświetlić "2 < 3", wpisz 2 &lt; 3 (znak specjalny <)
  • żeby wyświetlić "H&M" wpisz H&amp;M (znak specjalny &)

Skomplikowany HTML

Dlaczego muszę się posługiwać takimi brzydkim zapisem. H&amp;M wygląda jakby ktoś zhakował mi stronę :/ Taki "goły", brzydki kod. Owszem, troszkę tak to wygląda, ale pamiętajmy że tworząc strony internetowe, powinniśmy dbać przede wszystkim o to żeby strona wyglądała ładnie, a nie kod. Umieszczając brzydki zapis H&amp;M, dbamy o to żeby użytkownicy zobaczyli "H&M" :) Pomijam tutaj fakt, że właściwie to H&amp;M jest poprawnym zapisem H&M w HTML, i wydaje się niepoprawny tylko osobom początkującym.

Znaki specjalne są konieczną konsekwencją. Bez nich, mielibyśmy tylko trzy wyjścia:

  • Albo każdy znak byłby interpretowany byłby dosłownie - ale wtedy nie mielibyśmy języka znaczników tylko plik tekstowy (notepad)
  • Albo wyświetlanie znaków specjalnych byłoby niedozowlone - ale wtedy nie moglibyśmy nigdy wyświetlić pewnych znaków na stronie (np <, &)
  • Albo do określania specyfiki nie używalibyśmy tekstu, tylko danych binarnych - ale wtedy kodu HTML nie dałoby się pisać w edytorach tekstu.

Inne znaki specjalne

Nie tylko <, > oraz & to znaki specjalne. Czy widzisz inny znak specjalny w kodzie poniżej?

<div class="container">
  Welcome
</div>

Tutaj jest jeszcze kilka innych znaków specjalnych, które nie są interpretowane dosłownie. Np znak " przy class="container". W jaki sposób możemy dołączyć znak " do atrybutu HTML? Zapytasz pewnie po co, skoro klasy i tak nie mają nigdy cudzysłowów w nazwie. Celna uwaga, pamiętaj jednak że atrybutami HTML nie są tylko klasy, ale również inne elementy języka, jak np src, style, data, href i inne.

Dodajmy niestandardowy atrybut tekst do naszego elementu:

<div data-tekst="tekst to 'hej' ho">
</div>

Udało nam się dodać tekst tekst to 'hej' ho do atrybutu, ale jak moglibyśmy dodać wartość tekst to "hej" ho. Bardzo prosto, prawda? Wystarczy odwrócić cudzysłowy na apostrofy!

<div data-tekst='tekst to "hej" ho'>
</div>

Taki mały triczek zadziała jednak tylko wtedy kiedy w tekście nie ma jednocześnie " oraz ', oraz jeśli dane nie są dynamicznie dodawane do atrybutu, np poprzez JavaScript.

Jedynym rzetelnym sposobem jest specjalny zapis znaku ", a takim zapisem jest &quot;. Zapisem specjalnym apostrofou ' jest &apos;. Dzięki temu możemy np dodać wartość My name's "Jack sparrow"! do atrybutu. Jak ją zapisać?

<div data-tekst="My name&apos;s &quot;Jack sparrow&quot;!">
</div>

To prawda, wygląda to troszkę bardziej strasznie, ale to jedyny sposób żeby stworzyć stronę HTML wysokiej jakości - poprzez umiejętne obchodzenie się ze znakami specjalnymi.

O "twardych spacjach"

"Twarda spacja" jak początkujący nazywają ten znak, to dosyć okropna nazwa na bardzo pomocny element języka HTML, i niestety jest zupełnie mylnie rozumiany.

Wstęp #1

Jedynym z początkowych założeń HTML'a, było to że niektóre elementy zawijają tekst (jak np <textarea>, <p>), a inne nie (np. <pre>, lub dowolny element z white-space:nowrap;). Jeśli chcesz sobie zobrazować jak działa zawijanie wierszy, otwórz notatnik, wpisz tam dość długi tekst i włącz i wyłącz zwijanie tekstu.

long.text.png

long.text.wrapped.png

HTML został tak skonstruowany, że domyślnie każdy tekst jest zawijany, chyba że został umieszony w tagu <pre>, lub w bloku w którym jest styl white-space:nowrap;. Jeśli chcielibyśmy "wyłączyć" domyślne zawijanie tekstu, to powinniśmy własnie takim sposobem do tego podejść, tagiem <pre> lub odpowiednim stylem CSS.

HTML miał być również przyjazny do wprowadzania różnych przesunięć na stronie, marginesy, paddingi i bordery. Nazywa się to HTML Box Model. Jeśli chcielibyśmy zmienić pozycję elementu na stronie, to własnie takim sposobem powinniśmy do tego podejść, ustawiając odpowiedni styl margin, padding lub border. Bardziej zaawansowani użytkownicy mogą użyć flex, grid, table lub position. Można to jeszcze zrobić z float, ale nie zalecam tej metody.

Początkujący webmasterzy jednak, kiedy tworzą swoje strony nie znają tych technik, nie wiedzą też czym kierowali się twórcy HTML dodając takie elementy, nie znają więc odpowiedniego sposobu przesuwania tekstu lub odpowiedniej kontroli zawijania tekstu.

Wstęp #2 - prehistoria

Zanim powstał HTML, strony były wyświetlane po prostu jak tekst. Nie miały takich funkcji jak teraz, jak Box Model, FlexBox, position absolute, obrazków, ani żadnych innych takich funkcji. Tak na prawdę widzieliśmy "goły" plik tekstowy. Istniał jednak koncept zawijania tekstu! To właściwie była jedyna funkcja ówczesnych stron. Przeglądarki były tak zaprogramowane, żeby zawijać spacje zawsze (czyli właściwie tak jak HTML dzisiaj), ale do kontroli tego zawijania istaniały specjalne znaki. Nie było <pre> ani whitespace:nowrap; ponieważ nie istniał wtedy HTML ani CSS. Wpisanie <pre> skutkowałoby po prostu wyświetleniem napisu "<pre>". Dodawano wtedy specjalne znaki kontrolne (znak kontrolny to np. spacja, enter, tabulator). Były też takie znaki kontrolne jak: Non-breaking space (nie zawijająca spacja), oraz non-breaking hyphen (niezawijający myślnik). Używając takiego zapisu Witaj[non breaking space]Kamil, oraz żółto[non breaking hyphen]zielony zobaczylibyśmy Witaj Kamil oraz żółto-zielony, ale dwa dwa wyrazy nie byłyby nigdy "złamane", to znaczy nie byłyby zawinięte osobno.

Dawno temu, to był jedyny sposób kontroli zawijania tekstu.

Wstęp #3 - ignorowanie białych znaków

HTML został skonstrowany tak, by można było wpisać w nim w miarę przejrzysty kod.

Dlatego taki zapis, czyli <div>, nowa linia, spacja, spacja, Welcome, nowa linia, <div>

<div>
  Welcome
<div>

.. nie wyświetli nam: otwarty blok, nowa linia, spacja, spacja, welcome, nowa linia, zamknięty blok. Byłoby to bardzo męczące, gdybyśmy nie chcąc wyświetlić białych znaków musieli pisać <div>Welcome</div>. Nie pozwoliłoby to na umiejętne pisanie czystego kodu.

Z tego powodu białe znaki, tzn spacje, tabulatory i nowe linie są całkowicie ignorowane w kodzie HTML. Ale w kodzie, nie na stronie! Np zapis <br> nie zostanie zignorowany - tak, używa się go do wyświetlenia nowej linii na stronie, ale <br> sam w sobie nie jest białym znakiem.

Teraźniejszość

Wracając do początkujących webmasterów, jesli chcieliby przesunąć pewien tekst w lewo, a nie znają margin, padding, <pre>, whitespace:nowrap, border, flex ani żadnej innej metody pozycjonowania elementów, co mogą zrobić? Większość wpada na pomysł żeby przesunąć tekst w prawo spacjami:

Przed:

Welcome

Po:

    Welcome

Niestety nie widzą żadnej różnicy na stronie, ponieważ białe znaki na stronie są całkowicie ignorowane. Zadają wtedy pytanie na forum "Jak wyświetlić spację na stronie", i dostają odpowiedź, że jedynym sposobem jest użycie non-breaking space. Zauważ, że właściwie nie jest to, to czego pytający oczekuje. Pytający chciałby przesunąć swój tekst - powinien więc użyć margin, padding lub innej zalecanej formy. Jednak poprzez niepoprawne zadanie pytania, i poprzez nie zrozumienie HTML'a, tworzy nieoptymalne rozwiązanie.

"Twarda spacja" - poprawne użycie

Tzw. "twardych spacji" (okropna nazwa), czyli tak na prawdę "niełamiących białych znaków", ponieważ tym właśnie są, powinniśmy stosować tylko wtedy, kiedy chcemy oddzielić białym znakiem dwa słowa od siebie, tak by nie zostały nigdy złamane przez zawijanie tekstu. Takimi słowami może być np emotikona : ).

Jeśli dodamy taki kod

<div>
  Lubię Cię : )
</div>

to prawdopodbnie wyświetli się on tak

Lubię Cię : )

ale jeśli jednak z jakiegoś powodu <div> miałby mieć mniejszą szerokość, to może okazać się że tekst się zawinie tak:

Lubię Cię :
)

lub nawet tak

Lubię 
Cię : )

Drugi przykład nie jest taki zły, ale pierwszy już jest. Dwurkopek na górze, a nawias na dole całkowicie psuje ideę emotikony, powinniśmy dbać o to, by te dwa znaki nigdy się "nie rozdzieliły" przez zwijanie tekstu. Radą jest tutaj właśnie non-breaking spacje, czyli spacja nie łamiąca zawijania.

<div>
  Lubię Cię :&nbsp;)
</div>

Dzięki takiemu zabiegowi, nadal mam załamywanie tekstu w naszym bloku, ale : ) już się nie rozdzielą. To znaczy, że : ) albo będzie pierwszej linii, albo w dolnej. Ale ponieważ &nbsp; to non-breaking space, to nigdy nie zajdzie sytuacja w którym : będzie w jednej linii, a ) w drugiej. To jest właśnie idea korzystania z &nbsp; i nie powinno się jej stosować do żadnych innych celów.

Uwaga! Gdybyś chciał wprowadzić wyłączenie zawijania w całym bloku, nie dodawaj &nbps; zamiast spacji, tylko użyj <pre> lub whitespace:nowrap;.

"Twarda spacja" - niepoprawne użycie

Jak już widzieliśmy, początkujacy programiści używają non-breaking space - spacji nie łamiących zawijania tekstu, to przesunięcia swojego tekstu w prawo.

<div>
&nbsp;&nbsp;Tekst
</div>

dostaniemy

   Tekst

Jest to jednak niepoprawne zastosowanie tej encji, ponieważ po pierwsze teraz Tekst nie może być zawijany, a po drugie jego przesunięcie może być jedynie wielokrotnością powtórzeń znaki (tzn jedna taka spcja, dwie, trzy, etc.). Nie da się go np przesunąć o 2 piksele w ten sposób. Po drugie, ze zmianą czcionki, szerokość spacji rośnie, a więc i przesunięcie. Musielibyśmy wtedy wyświetlać inną ilość niełamiących spacji dla różnych wilkości czcionek. Rozwiązanie jest więc niepraktyczne i wręcz głupię. Lepszym narzędziem do odstępów jest margin, padding, border, flex (flexbox z CSS3), grid (gridbox z CSS3), table (tabela).

Nie korzystaj z &nbsp; do przesuwania tekstu w lewo lub w prawo.

Nienazwane znaki specjalne

We wcześniejszej części artykułu mówiłem ze wszystkie znaki specjalne mają swój specjalny zapis. Nie było to kłamstwo, jednak nie był to pełny obraz. Prawdą jest że tak na prawdę każdy znak ma swój zapis specjlny. Nawias, kropka, znaki interpunkcyjne, nawet akcenty i litery.

Taki zapis

<div>Witaj</div>

moglibyśmy zapisać tak

<div>&#87;&#105;&#116;&#97;&#106;</div>

Nie jest to jednak żaden trick, ani żaden sposób "kodowania strony", to po prostu specjalny zapis znaków W, i, t, a oraz j. Nie mają jednak one krótszej formy (jak &W; czy &i;), ponieważ nie miałoby to sensu. Znacznie prościej jest napisać Witaj, by były zinterpretowane domyślnie. Jednak ich zapis encjami nadal istnieje. Pełną listę nazwanych i nienazwanych encji możemy zobaczyć tutaj: https://www.freeformatter.com/html-entities.html

Zanki specjalne pokazane w tym artykule są "nazwane", tzn mają prostszy zapis - i tym prostszym zapisem się właśnie posługiwaliśmy (&lt;, &amp;, &quot;). Nie wszystkie znaki jednak mają prosty zapis, i wyglądają np. tak &#87;.

Pomocne encje

Czasem korzystanie z encji to konieczność - zapis < lub & na stronie nie ma racji bytu, bez ich takiego zapisania.

Są jednak znaki które interpretujemy dosłownie, np znak waluty, euro, funt, czy znak copyright lub paragrafu czy sekcji czy też towaru zastrzeżonego. Nie są to znaki specjalne, więc zapis ich dosłowny nie zepsuje nam strony, ale nie wszyscy mamy klawiatury na których mamy taki znak. Nie wszystkie czcionki edytorów kodu wyświetlają też te znaki poprawnie.

Dlatego dobrą praktyką jest, kiedy chcemy użyć znaku , ©, §, , zróbmy sobie przysługę, oraz czytelnikom i zamiast tego posłużmy się encjami: &euro;, &copy;, &sect;, &trade;. Nic złego się nie stanie jeśli ich nie użyjemy, nie będzie to też żadnym błędem; ale takie encje są przyjemniejsze dla czytelnika, i nie musimy się martwić o dobór odpowiedniej czcionki która wyświetli takie znaki.

Lista najbardziej popularnych encji

Encja HTML Wyjaśnienie Podgląd tekstowy
&lt; Dosłowny zapis znaku mniejszości (otwierający znak tagu HTML) <
&gt; Dosłowny zapis znaku większości (zamykający znak tagu HTML) >
&amp; Dosłowny zapis znaku ampersand (symbol encji) &
&quot; Dosłowny zapis cudzysłowu "
&apos; Dosłowny zapis apostrofu '

0 komentarzy