Dziś druga część cyklu na temat frameworka Semantic UI. Jej autorem jest Kacper Tylenda, który kontynuuje swoją serię, a dziś pokaże czy da się, za pomocą Semantic UI, stworzyć stronę bez użycia CSS… Zapraszam do lektury wpisu!

W pierwszym odcinku tej serii opisałem Semantic UI z perspektywy teoretycznej. Czy początkowa fascynacja przetrwa zderzenie z realnym wykorzystaniem opcji dostępnych w tym frameworku? O tym dowiecie się dzisiaj!

Wstępne założenia

Semantic UI wygląda na kombajn, dzięki któremu da się tworzyć strony bez użycia CSS. Właściwie oprócz podstawowej znajomości HTML nie musimy wiedzieć nic więcej żeby stworzyć prostą stronę WWW.

Jako, że żywo jestem zainteresowany tematem poszukiwania pracy na pozycji junior front-end developer robiąc research natrafiłem na setki stron typu “portfolio” ludzi znajdujących się w mojej sytuacji. Znakomita większość tych stron wygląda bardzo podobnie. Dzisiaj spróbuję zrobić takie portfolio z pomocą Semantic UI. Żeby nie było zbyt łatwo, do wyzwania dodam kilka dodatkowych założeń:

  • Używamjak najmniejszej ilości własnego CSS. Tylko w przypadku gdzie jest to niezbędne
  • Dobór kolorów nie jest tutaj istotny
  • Będę się starał wykorzystać jak najwięcej elementów wbudowanych w Semantic UI by pokazać pełnię możliwości (lub braki)

Także zapnijcie pasy, bo zaraz…

Zaczynamy

Struktura projektu będzie bardzo prosta. W pliku index.html umieszczę cały kod strony. Plik script.js pozwoli nam uruchomić dynamiczne funkcje Semantic UI. Do katalogu img wrzucimy też niezbędną nam grafikę. W razie czego stwórzmy również plik style.css

W standardowym szkielecie strony HTML, w pliku index dodam, pomiędzy znacznikami <head>, pliki semantic.min.css i style.css:``

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.10/semantic.min.css">
<link rel="stylesheet" href="style.css">

Wewnątrz znacznika <body> dodaję wymagane pliki JavaScript jquery.min.js, semantic.min.js a także nasz script.js:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.10/semantic.min.js"></script>
<script src="script.js"></script>

Teraz jesteśmy w pełni gotowi do rozpoczęcia projektu!

Nawigacja

Tworzenie strony zaczynam od górnej belki z nawigacją. Już na tym etapie pojawiły się pierwsze problemy

Bardzo ciężko było mi stworzyć strukturę odpowiednich klas dla gridu połączonego z guzikami żeby wszystko wyglądało tak jak bym chciał. Prawdopodobnie czas jaki włożyłem w opracowanie działającej nawigacji wystarczyłby żeby napisać wszystko samemu od podstaw. Jednak ostatecznie wszystko się udało i zawsze mogę zwalić winę na brak doświadczenia…

Semantic UI nie ma wbudowanej opcji “hamburgera” więc dla urządzeń mobilnych zastąpimy go modułem sidebar. Sidebar będzie “wypychany” przy użyciu funkcji sidebar(). Aby wszystko działało jak należy, content naszego portfolio musimy owinąć w div i nadać jej klasę pusher (klasa ta będzie odpychana przez sidebar, dlatego umieszczam go poza tą klasą):

<body>
  <!-- sidebar should be outside the "pusher" -->

  <div class="pusher">
    <!-- content pushed by the sidebar -->
  </div>

</body>

Stworzymy dwie wersje nawigacji:

  • dla komputerów
  • dla tabletów i telefonów

Całość nawigacji będzie znajdować się w znaczniku:

<nav class="ui grid">

W jego wnętrzu tworzymy dwa gridy - jeden dla komputerów, drugi dla urządzeń mobilnych.

Wersja dla komputerów

Wersja dla dużych ekranów wygląda w ten sposób:

<div class="computer only row">
  <div class="ui massive violet inverted fixed menu container">
    <div class="ui container">
      <a class="header item">Portfolio</a>
      <div class="right menu">
        <a class="item" href="#aboutme">About Me</a>
        <a class="item" href="#myprojects">My Projects</a>
        <a class="item" href="#contact">Contact</a>
      </div>
    </div>
  </div>
</div>

Klasy computer only row działają w ten sam sposób co klasa hidden w Bootstrapie i będą ukrywać kod znajdujący się wewnątrz tego znacznika dla wybranych przez nas wielkości ekranu.

W divie znajdującym się wewnątrz ustawiam klasy:

  • wielkość - massive
  • kolor - violet i inverted
  • przyklejenie do góry ekranu - fixed

Klasa container działa w ten sam sposób co w Bootstrapie - ogranicza maksymalną szerokość wyświetlanych elementów. Używając klas right menu przesuwamy elementy naszej nawigacji na prawą część ekranu.

Wersja dla urządzeń mobilnych

Przejdźmy jednak do ciekawszej części tej układanki czyli do wersji mobilnej:

<div class="tablet mobile only row">
  <div class="ui massive violet inverted fixed menu">
    <div class="ui container">
      <a class="header item">Portfolio</a>
      <div class="right menu">
        <a class="item icon"><i class="content icon"></i></a>
      </div>
    </div>
  </div>
</div>

Całość wygląda tutaj analogicznie do wersji dla większych ekranów. Jedyna różnica to jest taka, że zamiast linków nawigacji wyświetlam jeden link z ikoną “hamburgera”.

Wykorzystuję tutaj wbudowane ikony Semantic UI. Element <i> z klasami content icon pozwalają na wyświetlenie pożądanej, charakterystycznej ikonki (linia numer 6 w powyższym przykładzie).

Teraz musimy dodać do linku zdarzenie onclick, które “wypchnie” nasz sidebar (o tym jak go zrobić, za chwilę). Przejdźmy zatem do pliku script.js i dodajmy poniższy kod:

$(document).ready(function() {

  $('.item.icon').on('click', function () {
    $('.ui.sidebar')
        .sidebar('setting', 'mobileTransition', 'scale down')
        .sidebar('setting', 'transition', 'scale down')
        .sidebar('toggle');
  });

});

Korzystając z jQuery, po kliknięciu w link posiadającegy klasy item icon, odpalamy funkcje dostarczane przez sam Semantic UI! Mamy dostępnych sporo opcji dotyczących sposobu wysunięcia się sidebara, typu animacji, itd. Polecam przyjrzeć się opisowi w dokumentacji.

Wewnątrz znacznika <body> ale poza kontenerem z klasą pusher dodajemy sidebar zawierający nawigację dla urządzeń mobilnych:

<div class="ui right vertical sidebar violet inverted labeled icon menu">
  <a class="item" href="#aboutme">
    <i class="user icon"></i>
    About
  </a>
  <a class="item" href="#myprojects">
    <i class="laptop icon"></i>
    Projects
  </a>
  <a class="item" href="#contact">
    <i class="mail outline icon"></i>
    Contact
  </a>
</div>

Pierwszy div opisuje, za pomocą nadanych klas, nastepujące zachowania i opcje:

  • right vertical sidebar pionowy sidebar wysuwający sie z prawej strony
  • violet inverted - kolory
  • labeled icon menu - menu składające się z ikon i etykiet.

Ponownie wykorzystujemy wbudowane w Semantic UI ikony, których jest całe mnóstwo!

Nawigacja naszego Portfolio jest gotowa! Przechodząc dalej natkniemy się niestety na konieczność złamania zasady określonej we wstępie tego wpisu. Nie uda nam się bowiem obejść bez użycia CSS…

Przywitajmy się

Niestety przez użycie klasy fixed w naszej nawigacji (w celu “przyklejenia” jej do górnej krawędzi ekranu), kolejne elementy dodawane do naszego portfolio bedą znajdowały się pod nią. Musiałem więc użyć tutaj swojej klasy żeby przesunąć content w dół:

<div class="ui container section-header">
  <h1 class="ui center aligned header">Hello,
  <div class="sub header">It's me. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </div>
  </h1>
</div>

Jak widzisz, oprócz standardowej klasy container użyłem też własnej, którą nazwałem section-header. Jej style, zdefiniowałem w pliku style.css, a wyglądają one tak:

.section-header {
  margin-top: 150px;
  margin-bottom: 150px;
}

Dzięki temu tworzę przestrzeń wokół przywitania Gości na mojej stronie. Po raz pierwszy również stosuję tutaj formatowanie tekstu dodając klasy center aligned, których nazwy mówią (chyba) same za siebie…

Wykorzystuję też wbudowaną klasę sub header zmniejszając rozmiar fontów.

Ten etap był bardzo szybki i jeszcze mniej efektowny. Przejdźmy jednak do konkretów i przedstawmy się!

O mnie

Biały jest nudny! Zmienię zatem kolor tła dla sekcji aboutme!

<div id="aboutme" class="ui row grid">
  <div class="teal column">

  </div>
</div>

Wewnątrz grida (klasy ui row grid) tworzymy kolumnę w kolorze zielononiebieskim (kolor: teal; kolumna: column). Teraz podzielmy nasz ekran na dwie kolumny wstawiając, wewnątrz powyższego, znacznik:

<div class="ui two column stackable grid container">

</div>

Kolumny te bedą wchodziły pod siebie na mniejszych ekranach (klasa stackable). Wewnątrz utworzymy najpierw pierwszą, lewą kolumnę:

<div class="column">
  <img class="ui fluid circular image" src="img/bradley.jpg">
</div>

Wstawiłem do niej “moje” zdjęcie po lekkim retuszu w Photoshopie… Korzystamy z klasy fluid by rozciągnąć je na całą szerokość (oczywiście są tutaj dostępne również klasy dotyczące wielkości o których pisałem w pierwszej części tego tutoriala) i dodajemy klasę circular aby zdjęcie miało w pełni zaokrąglone rogi. Klasę możemy zamienić na rounded żeby rogi były tylko trochę zaokrąglone.

W prawej kolumnie wykorzystam grupowanie żeby uatrakcyjnić opis (więcej za moment). Całość składa się z czterech takich samych “modułów” więc pozwól, że przedstawię tutaj tylko ten, który pokazuje dodatkowe możliwości Semantic UI:

<div class="column">
  <h1 class="ui center aligned violet header">About Me</h1>
  <div class="ui items">
    <div class="item">
      <div class="item-icon">
        <i class="huge violet clockwise rotated cocktail icon"></i>
      </div>
    <div class="ui middle aligned content">
    <div class="ui purple header">Favourite Drink</div>
      <div class="description">
        <p class="ui yellow sub header">whisky</p>
      </div>
    </div>
  </div>
</div>

Najpierw tworzę nową kolumnę, a następnie dodaję do niej nagłówek w kolorze fioletowym (violet). Następnie otwieram grupę (klasy ui items) i dodaję pojedynczy element item. Po raz kolejny przegrałem tutaj ze wstępnymi założeniami i musiałem zastosować własną klasę item-icon. Niestety ikony nachodziły na nagłówki po prawej stronie i musiałem zwiększyć margines.

.item-icon {
  margin-right: 20px;
}

Najciekawszym fragmentem kodu wydaje się jednak zastosowanie klas clockwise rotated dla elementu <i>. Dzięki temu obrócimy naszą ikonę o 90 stopni zgodnie ze wskazówkami zegara. Alternatywnie możemy tutaj użyć również klas counterclockwise albo horizontally/vertically flipped. ``

Strona bez użycia CSS - podsumowanie

Wpis strasznie się wydłużył i jestem zmuszony podzielić go na dwie części. Na pełne podsumowanie pracy z Semantic UI przyjdzie jeszcze czas po skończeniu projektu Portfolio. Jednak jak sam zapewne zauważyłeś, pojawia się tutaj kilka problemów:

  • Duża dowolność przy tworzeniu gridu zmniejsza czytelność kodu - istnieje kilka sposobów na określenie ilości kolumn i ich szerokości. Wstępnie nie stanowi to problemu jednak przy pracy w zespole albo po dłuższej przerwie w pisaniu kodu będzie to stanowiło doskonały sposób na utratę dużej ilości czasu i nerwów.
  • Nie mamy do dyspozycji klas opisujących marginesy i paddingi (tak jak w bootstrapie) więc stworzenie całej strony bez użycia CSS jest niemożliwe.
  • Stworzenie belki nawigacji przysporzyło mi sporo problemów i dopiero metodą prób i błędów doszedłem do poprawnej struktury.

Jeśli masz ochotę to tutaj możesz zobaczyć kod - github, a także jak wygląda wynikowe Portfolio opisane powyżej - github pages.

Wnastępnym odcinku opiszę powstawanie sekcji “Moje Projekty” i formularza kontaktowego, a następnie podsumuję swoją przygodę z Semantic UI.


Wpis ten jest częścią większej serii postów na temat Semantic UI. Poniżej linki do wszystkich części serii: