25. Budowa podstron

> Dodaj do ulubionych

Jesteśmy już bardzo blisko ukończenia naszej witryny. Mamy główne menu rozwijane w CSS, stopkę oraz stronę główną. Mamy także już treść podstron, ale brakuje nam szablonu, w którym moglibyśmy te podstrony zaprezentować. Utworzymy go w tym rozdziale, a przy okazji nauczymy się niezwykle przydatnej techniki CSS o nazwie Flexbox.

Jak zwykle nasi projektanci przygotowali dla nas graficzną reprezentację tego, co mamy stworzyć, więc nam pozostaje tylko zastosować się do ich wytycznych i wskazówek, aby przełożyć to na kod HTML i CSS.

Spójrzmy na projekt szablonu podstrony naszej witryny:

Podstrona wersja finalna

Jak widać, w nagłówku ani stopce nie ma żadnych zmian. Natomiast zmieniła się część środkowa, czyli ta, w której do tej pory był tylko element main.

W odróżnieniu od strony głównej, struktura podstrony jest podzielona na dwie części — część właściwą po lewej i pasek boczny po prawej stronie.

Jak już wiemy, właściwą treść główną strony umieszczamy w elemencie main, natomiast do reprezentowania paska bocznego doskonale nadaje się element aside.

Struktura części środkowej

Postanowiliśmy podzielić część środkową naszych podstron na dwie części: jedna będzie reprezentowana przez element main zawierający treść artykułu, a druga będzie reprezentowana przez element aside zawierający komponenty paska bocznego.

Dodatkowo całość umieścimy w kontenerze div o identyfikatorze site-content, aby „spiąć” te dwie sekcje razem i ułatwić sobie pracę z nimi. Poniżej znajduje się odpowiedni kod HTML.

<div id="site-content">
  <main>
  </main>

  <aside id="sidebar">
  </aside>
</div> <!-- End #site_content -->

Elementowi main nie nadaliśmy żadnego identyfikatora, ponieważ na stronie powinien znajdować się tylko jeden taki element (nie licząc pewnych rzadkich specyficznych sytuacji).

Natomiast elementowi aside nadaliśmy identyfikator sidebar, ponieważ ten element może występować w różnych miejscach na stronie, natomiast pasek boczny jest tylko jeden (przynajmniej w naszej witrynie – gdyby było ich więcej, nadalibyśmy im odpowiednie identyfikatory typu sidebar-left i sidebar-right).

Zwróć też uwagę na komentarz za zamykającym znacznikiem </div>. Kod źródłowy stron potrafi być bardzo długi i bywa że zawiera wiele elementów div. Dodatek komentarzy oznaczających, gdzie się kończą ważne elementy strukturalne, czasami ułatwia pracę.

Mamy gotową podstawową strukturę kontenera środkowej części naszej strony. Gdybyśmy jednak teraz dodali treść do tych elementów, to nie zobaczylibyśmy takich eleganckich kolumn ustawionych obok siebie, jak w docelowym projekcie. Zamiast tego ustawiłyby się one jeden nad drugim.

To oczywiście żadne zaskoczenie, ponieważ zdefiniowaliśmy kilka elementów blokowych, a te bez żadnych dodatkowych ustawień układają się właśnie w sposób opisany powyżej.

Najprostszym sposobem na kolumnowe rozmieszczenie takich elementów strukturalnych strony jest użycie technologii CSS o nazwie Flexbox.

Podstawy Flexboksa

W CSS 2.1 zdefiniowano następujące cztery tryby rozmieszczenia elementów, z których trzy już znasz:

  • układ blokowy,
  • układ śródliniowy,
  • układ tabelaryczny (jeszcze go nie poznaliśmy, ale wkrótce poznamy),
  • układ pozycjonowany.

W CSS3 wprowadzono kolejny tryb rozmieszczenia elementów, o nazwie Flexbox (ang. Flexible box). Jest to technologia, która rozwiązuje dokładnie ten problem, z którym teraz się mierzymy – ułatwia ułożenie elementów na stronie w taki sposób, w jaki chcemy.

Wyobraź sobie sytuację, w jakiej obecnie się znaleźliśmy. Mamy dwa elementy blokowe — main i sidebar, które chcemy ustawić obok siebie, jak kolumny. Bez technologii Flexbox nie byłoby to takie łatwe.

Kiedyś jednemu z elementów przypisalibyśmy własność float o odpowiedniej wartości, aby „pływał” on po lewej lub prawej stronie drugiego. To rozwiązanie jednak nie daje nam wygodnej kontroli nad układem elementów, ich wzajemnymi relacjami oraz wymiarami.

Natomiast dzięki własnościom dodanym do CSS w module Flexbox uzyskanie potrzebnego nam efektu będzie wręcz banalne.

Aby włączyć tryb Flexbox, należy wybranemu elementowi pełniącemu rolę kontenera (u nas jest to element div o identyfikatorze site-content) zdefiniować własność display o wartości flex lub inline-flex. Od tej pory jest on tzw. kontenerem elastycznym (ang. flex container).

Kontener elastyczny obsługuje kilka specjalnych własności umożliwiających rozmieszczenie na różne sposoby elementów będących jego dziećmi.

Wszystkie elementy dzieci kontenera elastycznego automatycznie stają się jednostkami elastycznymi (ang. flex item), czyli zaczynają obsługiwać specjalny zestaw własności z modułu Flexbox przeznaczonych dla jednostek elastycznych. W naszym przypadku jednostkami elastycznymi są elementy main i aside o identyfikatorze sidebar.

Wracając do naszego projektu podstrony z początku rozdziału, widzimy w nim, że element main zajmuje mniej więcej 70% szerokości kontenera, a element aside – pozostałe 30%. Zdefiniujemy więc im takie ustawienia i sprawdzimy, co się stanie (dodamy też kolory tła i wysokość, aby elementy były widoczne):

main {
  background-color: antiquewhite;
  width: 70%;
  height: 200px;
}
#sidebar {
  background-color: lightpink;
  width: 30%;
  height: 200px;
}

Efekt zastosowania tych reguł CSS jest następujący:

Szerokość elementów flexbox

Zgodnie z oczekiwaniami elementy ułożyły się jeden pod drugim oraz pierwszy zajmuje 70%, a drugi 30% szerokości kontenera.

Aby ustawić je tak, jak chcemy, włączymy tryb Flexbox w ich kontenerze. W tym celu dodajemy do arkusza stylów poniższą regułę CSS, która uczyni element #site-content kontenerem elastycznym:

#site-content {
  display: flex;
}

Teraz nasza strona wygląda tak, jak na poniższym zrzucie ekranu:

Efekt włączenia Flexbox

Nasze elementy zostały automatycznie ustawione jeden obok drugiego. Jest to zasługa domyślnego ustawienia własności kontenerów elastycznych o nazwie flex-direction.

Własność flex-direction

Własność flex-direction określa kierunek rozmieszczenia elementów elastycznych. Przyjmuje ona cztery wartości:

  • row – wartość domyślna, która ustawia elementy w rzędzie.
  • row-reverse – ustawia elementy w rzędzie w odwróconej kolejności.
  • column – ustawia elementy w pionie.
  • column-reverse – ustawia elementy w pionie w odwróconej kolejności.

W poniższym oknie możesz wypróbować efekt zastosowania każdego z tych ustawień w praktyce.

See the Pen Test flex-direction by Łukasz Piwko (@shebangpl) on CodePen.

Jak widać, technologia Flexbox znacznie ułatwia rozmieszczenie elementów w kontenerze na różne sposoby. Na naszej nieskomplikowanej stronie wystarczyło użyć tylko jednej własności z jej arsenału, aby uzyskać pożądany efekt.

Moduł Flexbox zawiera wiele innych własności, ale nie on jest tematem tego rozdziału, więc poniżej przedstawiam tylko zwięzły opis paru innych, które mogą się przydać w codziennej pracy.

Własność flex-wrap

Własność kontenera elastycznego flex-wrap określa sposób zawijania elastycznych elementów w kontenerze. Przyjmuje trzy wartości:

  • wrap – elementy normalnie przechodzą do kolejnych wierszy, gdy brakuje miejsca w poziomie.
  • wrap-reverse – elementy przechodzą do kolejnych wierszy, ale w odwrotnej kolejności.
  • nowrap – elementy nie są przenoszone do kolejnych wierszy.

Zmień rozmiar poniższego elementu, aby zobaczyć działanie tych wartości w akcji.

wrap

1
2
3
4
5
6
7
8
9
10

wrap-reverse

1
2
3
4
5
6
7
8
9
10

nowrap

1
2
3
4
5
6
7
8
9
10

Własność justify-content

Własność kontenera elastycznego justify-content określa rozmieszczenie elementów w poziomie. Przyjmuje następujące wartości:

  • center – elementy są wyrównane do środka
  • flex-end – elementy są wyrównane do prawej
  • flex-start – elementy są wyrównane do lewej
  • space-around – elementy są rozmieszczone tak, że każdy z nich otacza taka sama ilość przestrzeni
  • space-between – elementy są rozmieszczone równomiernie od lewej do prawej
  • space-evenly – elementy są rozmieszczone w taki sposób, że odstęp między wszystkimi parami jest taki sam

Własność align-items

Ta własność, podobnie jak justify-content, także służy do wyrównywania elementów, ale w pionie, a nie w poziomie. Przyjmuje ona kilka wartości. Na przykład wartość center powoduje wyśrodkowanie jednostek elastycznych w pionie, flex-start – wyrównanie do górnej krawędzi kontenera, a flex-end – do jego dolnej krawędzi.

To tylko mała próbka możliwości technologii Flexbox, więc warto poznać ją bliżej we własnym zakresie. W tej chwili jednak interesuje nas stylizacja szablonu podstrony naszej witryny. Najpierw dokończymy formatowanie sekcji treści właściwej.

Struktura sekcji treści właściwej

W sekcji treści właściwej (w elemencie main) mamy niewiele do zrobienia. Jest tam tylko nagłówek reprezentujący imię i nazwisko osoby, której dotyczy artykuł, a pod nim mamy już tekst opisujący daną osobę.

Oznacza to, że musimy tylko dodać element article, który będzie reprezentował nasz wpis, a w nim – element h2 reprezentujący nagłówek tego wpisu.

<main>
  <article>
    <h2>Ciekawa osoba</h2>
  </article>
</main>

Stylizacja elementu main

Teraz wystarczy odpowiednio sformatować zawartość nagłówka i będzie można przejść do paska bocznego. Spójrz na poniższą regułę CSS, która została napisana według wytycznych naszych projektantów i zgodnie z ich projektem graficznym:

main > article h2:first-of-type {
  margin-top: 0;
  margin-bottom: 30px;
  text-align: center;
}

Selektor dziecka main > article daje nam pewność, że odniesiemy się tylko do elementu article znajdującego się bezpośrednio w elemencie main (a nie w jakimś jego potomku).

Ponadto wyzerowaliśmy górny margines, ustawiliśmy dolny margines na 30 pikseli oraz wyśrodkowaliśmy treść nagłówka. I to wszystko w tej sprawie. Pod nagłówkiem wkleimy już treść artykułu.

Teraz przejdziemy do paska bocznego, który jest odrobinę bardziej skomplikowany.

Struktura paska bocznego

Pasek boczny w naszym projekcie zawiera trzy sekcje: Zobacz również, Reklama i O autorze. Do oznaczania tego typu niepowiązanych ze sobą w żaden szczególny sposób komponentów doskonale nadaje się element HTML5 section. Poniżej znajduje się docelowa struktura HTML naszego paska bocznego:

<aside id="sidebar">
  <section>
    <h2>Zobacz również</h2>
    <ul>
      <li><a href="#">Pozycja 1</a></li>
      <li><a href="#">Pozycja 2</a></li>
      <li><a href="#">Pozycja 3</a></li>
      <li><a href="#">Pozycja 4</a></li>
      <li><a href="#">Pozycja 5</a></li>
      <li><a href="#">Pozycja 6</a></li>
    </ul>
  </section>
  <section>
    <h2>Reklama</h2>
  </section>
  <section>
    <h2>O autorze</h2>
    <p>To jest krótka notatka o autorze. Autor tej strony jest ze wszech miar niezwykłym i mądrym człowiekiem, który przysłużył się już ludzkości na wiele sposobów.</p>
  </section>
</aside>

Jak widać każdy z komponentów paska bocznego jest zbudowany według określonego schematu: element section + nagłówek h2 + treść dodatkowa.

Stylizacja paska bocznego

Najpierw zdefiniujemy ustawienia CSS dla samego kontenera, a następnie dodamy reguły dotyczące komponentów. Spójrz na poniższy kod:

#sidebar {
  width: 30%;
  text-align: left;
  border-left: 1px solid #ddd;
  margin-left: 40px;
}

Za pomocą tej reguły ustawiliśmy szerokość paska bocznego na 30% szerokości kontenera, wyrównaliśmy tekst do lewej, zdefiniowaliśmy lewą krawędź obramowania o grubości jednego piksela i szarym kolorze oraz odsunęliśmy pasek boczny na odległość 40 pikseli od elementu main.

Teraz nasz pasek boczny wygląda tak:

Pasek boczny pierwszy

Kontener jest już odpowiednio ustawiony względem sąsiedniego elementu, ale w jego wnętrzu panuje jeszcze spory bałagan. Teraz zdefiniujemy właściwości poszczególnych komponentów.

Stylizacja komponentów paska bocznego

Pracę nad komponentami paska bocznego zaczniemy od uporządkowania odstępów. Najpierw zwiększymy odstęp między poszczególnymi elementami section i odsuniemy ich zawartość od lewej krawędzi, aby dodać trochę przestrzeni:

#sidebar section {
  margin-top: 45px;
  padding-left: 25px
}

Ta reguła dotyczy jednak wszystkich elementów section w pasku bocznym, a więc także pierwszego, który jednak powinien mieć zerowy górny margines. Aby pozbyć się tego problemu, użyjemy pseudoklasy :first-of-type, która odnosi się do pierwszego elementu potomnego określonego typu:

#sidebar section:first-of-type {margin-top: 0;}

Teraz wszystkie elementy section w elemencie #sidebar, z wyjątkiem pierwszego, będą miały górny margines o szerokości 45 pikseli. Natomiast pierwszy z nich nie będzie miał tego marginesu w ogóle. Teraz nasz pasek boczny wygląda tak:

Pasek boczny drugi

Następnie zajmiemy się nagłówkami h2 w elementach section:

#sidebar h2 {
  margin-top: 0;
  margin-bottom: 14px;
  font-size: 1.2em;
}

Zlikwidowaliśmy margines górny, ustawiliśmy margines dolny na 14 pikseli, aby odsunąć trochę treść od nagłówka oraz zmieniliśmy rozmiar pisma na 1,2 rozmiaru pisma elementu nadrzędnego. Efekt zastosowania tych zmian jest następujący:

Pasek boczny trzeci

Pozostało nam jeszcze tylko zająć się listami i kolorem łączy. Spójrz na poniższe reguły CSS:

#sidebar ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  font-size: 95%
}
#sidebar li {
  margin-bottom: 7px;
}
#sidebar a {
  color: #786d6d
}

Pierwsza z tych reguł likwiduje punktory, marginesy i dopełnienie listy oraz zmniejsza jej rozmiar pisma. Druga ustawia odstęp między elementami listy na 7 pikseli. Trzecia zmienia kolor odnośników w pasku bocznym na nieco jaśniejszy niż w nawigacji głównej.

Efekt wprowadzenia tych reguł do arkusza stylów jest następujący:

Pasek boczny czwarty

Wszystko wygląda dobrze, tylko brakuje nam jeszcze grafik, które powinny już znajdować się na Twoim dysku i czekać na swoją kolej. Użyjemy ich teraz.

Pierwszy jest komponent reklamowy, w którym umieścimy obraz o nazwie newsboy.png:

<section>
  <h2>Reklama</h2>
  <img src="img/newsboy.png" alt="Chłopiec z gazetą" width="150" height="240" class="centered-img">
</section>

Jeśli przyjrzysz się naszemu projektowi, to zauważysz, że grafika reklamy jest wyśrodkowana. W naszym kodzie odpowiada za to klasa centered-img, której definicja CSS znajduje się poniżej:

.centered-img {
  display: block;
  margin: 30px auto;
}

Za pomocą tej reguły zamieniliśmy element img w element blokowy, a następnie nadaliśmy mu 30-pikselowy margines górny i dolny oraz automatyczny margines lewy i prawy. Dzięki temu każdy element przypisany do klasy centered-img będzie ustawiał się na środku kontenera.

Projektanci stron internetowych lubią definiować takie ogólne klasy, aby następnie móc ich używać do formatowania wielu różnych elementów na stronie. Można nawet rozważyć usunięcie członu -img z nazwy naszej klasy, jeśli planujemy stosowanie jej także do elementów innego typu.

Drugi komponent zawierający grafikę to sekcja O autorze. W tym przypadku zdjęcie autora jest otoczone tekstem z lewej strony. Ponownie zdefiniujemy odpowiednie ustawienia w postaci klasy na wypadek gdybyśmy jeszcze w innych miejscach chcieli użyć podobnego formatu:

.float-right {
  float: right;
  margin: 10px 0 10px 10px;
}

Wszystkie marginesy, oprócz prawego, mają szerokość 10 pikseli. Prawy został usunięty, ponieważ chcemy, aby nasz element „spływał” do samej krawędzi swojego kontenera.

Ukończyliśmy pracę nad naszym szablonem podstrony, więc możemy przejść do wstawiania treści artykułów.

Dodawanie treści artykułów

Od kiedy mamy gotowy szablon podstrony, wstawienie do niego treści jest już tylko kwestią skopiowania odpowiedniego fragmentu stronu i wklejenia go w odpowiednim miejscu na innej stronie.

Na pierwszym miejscu naszego menu głównego znajduje się pozycja Paul Erdős, więc od tej strony zaczniemy przenosiny.

Najprościej będzie utworzyć nową stronę o nazwie erdos.html i skopiować do niej zawartość szablonu, po czym wkleić do szablonu treść artykułu o Paulu Erdősie.

W związku z tym wykonaj następujące czynności:

  1. Zmień nazwę starej strony o Erdősie na erdos-old.html.
  2. Utwórz nowy pusty plik HTML o nazwie erdos.html.
  3. Skopiuj do nowego pliku erdos.html zawartość szablonu podstrony.
  4. W elemencie h2 w elemencie article nowego pliku erdos.html wpisz Paul Erdős.
  5. Otwórz w edytorze plik erdos-old.html i skopiuj z niego zawartość elementu body.
  6. Wklej zawartość elementu body z pliku erdos-old.html pod elementem h2 w elemencie article nowego pliku erdos.html.

Teraz otwórz swoją nową stronę, aby sprawdzić, jak wygląda. A powinna ona wyglądać mniej więcej tak:

Gotowa podstrona o Erdosie

Jeśli Twoja strona też tak wygląda, to należą Ci się gratulacje za wykonanie świetnej roboty!

Aby nasza strona nie była tak bardzo anonimowa, powinniśmy jeszcze dodać do niej nazwisko autora z danymi kontaktowymi. Tego typu informacje umieszczamy w elemencie address.

Dane autora witryny

Dane kontaktowe autora można umieścić w elemencie address. Jeśli znajduje się on w elemencie article, to odnosi się do treści tego elementu. Jeśli natomiast znajduje się w elemencie body (nie jest objęty elementem article), to odnosi się do autora całej strony. Poniżej znajduje się przykład użycia tego elementu:

<address>
  Autorem tej witryny jest <a href="/autorzy/profesor-kodecki/>Profesor Kodecki"</a>.
</address>

Wstawienie tego kodu na stronę pozostawimy już jako ćwiczenie do samodzielnego wykonania.

Prawie ukończyliśmy pracę nad naszą witryną. Pozostały nam jeszcze strony, do których odnośniki znajdują się w stopce. Jedna z nich nazywa się Kontakt.

Na stronie kontaktowej umieścimy formularz, za pomocą którego użytkownicy naszej witryny będą mogli wysłać nam wiadomość. No, może nie do końca… Formularze HTML to komponenty dwuczęściowe – składają się z interfejsu użytkownika, który tworzy się za pomocą HTML i CSS, oraz ze skryptów serwerowych, które przetwarzają wprowadzone dane.

To jest kurs HTML i CSS, więc nauczysz się tworzyć część interfejsową. Natomiast do opracowania drugiej części potrzebna jest znajomość jednego z języków programowania działających na serwerze, np. PHP albo Python.

W następnym rozdziale nauczysz się tworzyć formularze HTML.

Podsumowanie

  • Treść główną strony można umieścić w elemencie HTML5 main.
  • Treść właściwą wpisu na stronie można umieścić w elemencie HTML5 article.
  • Do rozmieszczania elementów na stronie doskonale nadaje się technologia Flexbox.
  • Aby zamienić dowolny element w kontener elastyczny należy użyć deklaracji CSS display: flex lub display: inline-flex.
  • Elementy będące bezpośrednimi potomkami kontenera elastycznego nazywają się jednostkami elastycznymi.
  • Własność flex-direction określa kierunek ułożenia jednostek elastycznych w kontenerze elastycznym
  • Własność flex-wrap określa sposób zawijania jednostek elastycznych w kontenerze elastycznym.
  • Własność justify-content określa sposób wyrównania poziomego jednostek elastycznych w kontenerze elastycznym.
  • Własność align-items określa sposób wyrównania pionowego jednostek elastycznych w kontenerze elastycznym.
  • Pasek boczny strony można umieścić w elemencie HTML5 aside.
  • Sekcje paska bocznego można oznaczyć elementem HTML5 section.
  • Element HTML5 address oznacza dane kontaktowe autora wpisu lub całego dokumentu.

Ćwiczenia

  1. Na wszystkich stronach naszej witryny brakuje ważnego elementu – metaopisu. Jeśli nie pamiętasz, co to jest, wróć do rozdziału o podstawowej strukturze dokumentu i przeczytaj w nim opis elementu meta description. Po odświeżeniu wiadomości dodaj ten element do wszystkich podstron i do strony głównej.
  2. Zmień kolejność komponentów paska bocznego, aby przekonać się, że rzeczywiście można to swobodnie robić.
  3. Zdjęcie Erdősa wydaje się za duże. Popraw je tak, aby lepiej wyglądało.
  4. Utwórz pozostałe dwie podstrony witryny.
  5. Uporządkuj arkusz stylów. Usuń niepotrzebne reguły i podziel reguły na sekcje, które możesz oznaczyć za pomocą komentarzy.
  6. W rozdziale o stylizacji strony głównej zostały opisane wymagania dotyczące odnośników w treści artykułów. Oto one:
    1. Odwiedzone odnośniki w treści artykułów powinny być „przygaszone”
    2. Po najechaniu kursorem na odnośnik w treści artykułu powinno pojawiać się podkreślenie oraz kolor powinien zmieniać się na granatowy (tak jak w całej witrynie)
    Napisz odpowiednie reguły CSS.
  7. W pasku bocznym w sekcji Zobacz również na każdej podstronie dodaj linki do pozostałych dwóch podstron. Możesz dodać też kilka imitacji odnośników, aby było tam więcej treści i aby pasek wyglądał atrakcyjniej.
  8. Zmień notatkę o autorze na własną i dodaj własne zdjęcie.
  9. Dodaj własną reklamę do paska bocznego.
  10. W szablonie podstrony element title zawiera tylko tekst „Ciekawi ludzie”, przez co każda strona na karcie okna przeglądarki wygląda tak samo. Popraw to.
  11. Może pamiętasz z rozdziału o stylizacji strony głównej poniższą regułę CSS:

    a:hover {
      color: navy !important;
    }

    Usuń z niej deklarację !important i sprawdź, co się stanie z odnośnikami w pasku bocznym. Wiesz, dlaczego tak się stało? Umiesz to naprawić bez użycia deklaracji !important?