Dziś ostatnia już część serii autorstwa Kacpra Tylendy na kontrowersyjny temat frameworka Semantic UI. Fraza zawarta w tytule: “ile to kosztuje i czemu tak drogo” może sugerować jakie jest ostateczne zdanie autora o tym rozwiązaniu - ale więcej znajdziesz w tekście… W związku z tym zapraszam do jego przeczytania!

Minęły już dwa tygodnie od ostatniej części mojej mini serii wpisów dotyczących wykorzystania Semantic UI w praktyce. Czas wznowić serię i jednocześnie zakończyć nasz projekt. Dla ułatwienia przypomnę tutaj nasze założenia sprzed rozpoczęcia prac:

  • 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ę jego możliwości (lub też jego braki).

Wpis prawdopodobnie znowu będzie dość obszerny więc nie marnujmy czasu i przejdźmy do konkretów.

W poprzedniej części serii rozpocząłem budowę przykładowego portfolio - jeśli go nie czytałeś to zachęcam aby to zrobić. Do tej pory mamy zrobione trzy moduły naszego portfolio - nawigację, wiadomość powitalną i dział “o mnie”. Dzisiaj dołożymy kolejne trzy sekcje.

Nasze projekty, czyli element “reveal”

Na wstępie przypomnę, że cały kod umieszczamy wewnątrz elementu div o klasie pusher ze względu na menu dla urządzeń mobilnych. Zacznijmy od stworzenia pojemnika na kontent naszej nowej sekcji wraz z tytułem:

<section id="projects" class="ui container projects-container">
  <h1 class="ui left aligned huge header">
    <i class="settings icon"></i>
    <div class="content">
      My projects
      <div class="sub header">Few work examples</div>
    </div>
  </h1>
</section>

Najpierw do znacznika section dodajemy standardową klasę ui container. Następnie tworzymy bardzo duży nagłówek (klasy huge header), który będzie wyrównany do lewej strony (klasy left aligned).

Nagłówek ten będzie się składał z trzech elementów: ikony (klasy settings icon), głównego nagłówka i podpisu pod nim (klasy sub header). Niestety musimy tutaj wspomóc się naszym własnym CSS i, jak we wcześniejszych przypadkach, dodamy trochę przestrzeni na górze i na dole tworząc style dla sekcji #projects:

.projects-container {
  padding-top: 60px;
  padding-bottom: 30px;
}

Przedstawienie projektów

Teraz przejdźmy do konkretów czyli sposobu w jaki przedstawimy nasze prace. Wstawmy obrazek przedstawiający nasz projekt, a następnie po najechaniu na niego myszką zmieńmy go w opis pracy, jaka została wykonana. Do tego celu Semantic UI dostarcza klasę reveal. Za chwilę pokażę jak z niej skorzystać.

Na potrzeby przykładu wykorzystamy kilka screen shotów skopiowanych ze strony Awwwards. Pliki wrzuciłem do folderu img i są gotowe do wykorzystania. Spójrzmy teraz na pełen kod pierwszego naszego elementu “reveal”:

<article class="ui grid one column row project">
  <div class="column">
    <div class="ui move reveal">
      <div class="visible content">
        <img src="img/Rmagazine.jpg" class="ui fluid image" alt="r-magazine">
      </div>
      <div class="hidden content">
        <div class="ui inverted segment">
          <h2 class="ui center aligned yellow inverted header">Rmagazine</h2>
          <h4 class="ui center aligned olive inverted header"> r-magazine.world </h4>
          <h5 class="ui center aligned teal inverted header">Rmagazine is a lifestyle digital magazine entirely directed by ROLA, one of Japanese biggest celebrities.</h5>
        </div>
      </div>
    </div>
  </div>
</article>

Najpierw rozpoczynamy nasz jednokolumnowy grid (klasy one column row). Ponownie będziemy musieli dodać trochę przestrzeni pomiędzy elementami, dlatego dodajemy własną klasę project, która w pliku style.css wygląda następująco:

.project {
  padding-top: 30px;
}

Następnie, korzystając ze wspomnianej klasy reveal, określamy w jaki sposób ma wyglądać animacja danego elementu (w naszym przypadku move). Dostępnych mamy jeszcze kilka sposobów animacji np. move right albo rotate left. Polecam potestować we własnym zakresie. Następnie musimy utworzyć dwa elementy div:

  • Pierwszy będzie widoczny w momencie załadowania strony przez użytkownika (klasy visible content) - w naszym przypadku jest to screen shot. Chcemy żeby dopasował się on do wielkości naszego pojemnika dlatego nadajemy mu klasę fluid.
  • Drugi będzie elementem ukrytym, który będziemy animować podczas akcji hover (klasy hidden content). W naszym przypadku będzie to krótki opis projektu, który “wykonaliśmy”. Przy opisie naszych prac odwracam kolory używając klas inverted segement, a następnie nadaje kolory naszym nagłówkom (klasy yellow inverted) i wyrównuję tekst do środka (klasy center aligned).

W analogiczny sposób pokazujemy kolejne dwa “nasze” projekty. W ten sposób kończymy kolejny etap przedstawienia projektów.

Skontaktuj się ze mną, czyli formularze i ich walidacja

Kolejny niezbędny element to formularz kontaktowy. Zacznijmy od zmiany tła dla sekcji “Kontakt”, a także utworzenia nagłówka podobnego do tego z sekcji “Projekty”:

<section id="contact" class="ui row grid contact-row">
  <div class="teal column">
    <div class="ui container container-padding">
      <h1 class="ui left aligned huge header">
        <i class="mail icon"></i>
        <div class="content">Contact me
          <div class="sub header">Checking form validations methods.</div>
        </div>
      </h1>
    </div>
  </div>
</section>

Nie będę się tutaj rozwodził na temat użytych klas, ponieważ takich samych metod używałem albo w pierwszym odcinku tworzenia portfolio, albo w obecnym. Niestety ponownie musiałem dodać padding, żeby wszystko było bardziej przejrzyste:

.contact-row {
  padding-top: 60px;
}
.container-padding {
  padding-top: 60px;
  padding-bottom: 30px;
}

Formularz kontaktowy

Przejdźmy do sedna całości czyli utworzenia formularza, dzięki któremu goście będą mogli się z nami skontaktować:

<form class="ui equal width form">
  <div class="fields">
    <div class="required field">
      <label>First Name</label>
      <input name="firstname" type="text" placeholder="First Name">
    </div>
    <div class="required field">
      <label>Last Name</label>
      <input name="lastname" type="text" placeholder="Last Name">
    </div>
  </div>
  <div class="required field">
    <label>Email Address</label>
    <input name="email" type="email" placeholder="Email Address">
  </div>
  <div class="required field">
    <label>Your Message</label>
    <textarea name="message" rows="4">Your Message</textarea>
  </div>
  <div class="field">
    <input type="submit" value="Send Email" class="ui big olive button">
  </div>
  <div class="ui error message"></div>
</form>

Do znacznika form dodajemy klasy Semantic UI: ui form. W moim przypadku dodałem jeszcze equal width. Pozwoli nam to stworzyć dwa “inputy” o równej szerokości znajdujące się w jednej linii. Aby to zrobić, w następnym “divie” informujemy Semantic UI o grupie “inputów” fields, a następnie dodajemy pola tekstowe “First Name” oraz “Last Name”.

Klasa required informuje naszych gości, że pole jest wymagane (czerwona gwiazdka przy etykiecie z nazwą danego pola). Następnych pól nie trzeba chyba tłumaczyć, bo wszystko robimy analogicznie do pierwszych dwóch. Wysokość pola <textarea> określamy ilością wierszy. Dla naszego przycisku Submit dodajemy jedynie klasy zmieniające kolory i wielkość (big olive).

Walidacja formularza

Element div posiadający klasy ui error message będzie nam potrzebny do wyświetlenia błędów przy walidacji formularza. Aby jej dokonać musimy przejść do pliku script.js, gdzie wcześniej konfigurowaliśmy już nawigację dla urządzeń mobilnych. Oto przykładowy kod walidacji dla naszego formularza:

$('.ui.form').form({
  on: 'submit',
  fields: {
    firstname: {
      identifier: 'firstname',
      rules: [
        {
          type: 'empty',
          prompt: 'Please fill First Name input'
        }
      ]
    },
    lastname: {
      identifier: 'lastname',
      rules: [
        {
          type: 'empty',
          prompt: 'Please fill Last Name input'
        }
      ]
    },
    email: {
      identifier: 'email',
      rules: [
        {
          type: 'email',
          prompt: 'Please enter valid email address'
        }
      ]
    },
    message: {
      identifier: 'message',
      rules: [
        {
          type: 'minLength[20]',
          prompt: 'Please enter minimum of 20 characters'
        }
      ]
    },
  }
});

Najpierw dokonujemy selekcji naszego formularza używając standardowej składni jQuery, a następnie uruchamiamy funkcję form służącą do konfiguracji walidacji formularza wbudowanej w Semantic UI (tutaj więcej na ten temat). W przekazanym do tej funkcji obiekcie określmy kiedy sprawdzenie poprawności wypełnionych pól ma zostać przeprowadzone - on: submit. Dostępne są jeszcze on blur i on change.

Następnie ustalmy w jaki sposób walidacja ma się zachowywać i jakie błędy ma wyświetlać. Dla pól tekstowych (First Name i Last Name) ustaliłem, że formularz nie może być pusty. Mail ma być poprawnym adresem email, a pole wiadomości musi zawierać co najmniej 20 znaków (minLegth[20]). Jeśli wystąpią błędy informacja o nich (zawartość prompt) zostanie wyświetlona w elemencie div poniżej przycisku submit.

W tym module nie będzie już dla nas żadnych nowości:

<footer class="ui row grid">
  <div class="violet column">
    <h3 class="ui center aligned yellow header">All rights reserved 2017</h3>
  </div>
</footer>

Po raz kolejny używam kilku “szalonych” kolorów i kończę pracę nad naszym “Portfolio”.

Podsumowanie, czyli ile to kosztuje?

Pytanie przewrotne bo oczywiście z Semantic UI korzystać możemy za darmo. Dla większości z nas czas jest wartościową walutą i tutaj możemy stracić najwięcej. Oczywiście poziom wystarczający do zakodowania prostej strony internetowej osiągniemy tutaj bardzo szybko. Przy podstawowej znajomości HTML i spędzeniu dwóch-trzech godzin z dokumentacja Semantic UI będziemy w stanie zacząć pracę. Jednak problem pojawi się w momencie kiedy będziemy chcieli dodać coś od siebie. Prawdopodobnie większość ludzi, którzy potem spojrzą w nasz kod będzie przerażona ilością!important jakich będzie trzeba użyć by kontrolować naszą witrynę.

W poprzednim odcinku pisałem już o kosztach związanych z używaniem gridu. Istnieje wiele sposobów na osiągnięcie zamierzonych efektów. W przypadku pracy w grupie kod jaki stworzymy może być koszmarnie trudny do ogarnięcia - na przykład kiedy każdy postanowi inaczej zapisywać kolumny, co jest możliwe! Sam grid dzielący się na 16 kolumn, po zastanowieniu, nie ma większego sensu w sytuacji kiedy najczęściej dzielimy stronę na jedną, dwie, trzy lub maksymalnie cztery kolumny.

Kiedy czytałem dokumentację i przeglądałem przykłady wykorzystania poszczególnych elementów wyglądały one dość dobrze. Jednak jeśli spojrzysz na stronę, którą zrobiłem dostrzeżesz dziesiątki niedoróbek. Weźmy jako przykład element reveal, gdzie w wersji widocznej wstawiliśmy zdjęcie, a w wersji ukrytej tekst na czarnym tle. Czarne tło nie tworzy się na wysokość naszego obrazka, tylko na wysokość tekstu. “Bajer” ten zamiast wyglądać efektownie wygląda co najwyżej biednie.

Czy warto w to brnąć?

Zwróćmy też uwagę, że całe pliki css i js zajmują tutaj prawie 1MB co znacząco spowolni wczytywanie naszej strony, a ile takich elementów będziemy wstawiać na stronie? Dwa? Trzy? Zdecydowanie lepiej włożyć tutaj trochę więcej pracy i napisać wszystko samemu, od początku i porządnie. Wstępnie zajmie to nam zdecydowanie więcej czasu, ale nie będziemy mieli żadnych problemów z formatowaniem i spokojnie możemy używać tego w dalszych projektach. Początkowo poświęcony czas bardzo szybko zwróci się nam dzięki przejrzystości kodu.

Rozpoczynając serię artykułów na temat Semantic UI byłem bardzo pozytywnie nastawiony do tego frameworka. Jednak rzeczywistość okazała się dużo gorsza niż moje wyobrażenie. Już przy tworzeniu nawigacji do “Portfolio” miałem ogromną ochotę zrezygnować. Później było już łatwiej i szybciej jednak, ani efekt końcowy, ani styl pracy z Semantic UI, nie zachęciły mnie do przedłużenia tej przygody. Wydaje mi się, ze czas poświęcony na stworzenie “potworka”, do którego pełen kod zamieszczam poniżej byłby krótszy gdybym postanowił zakodować wszystko samemu używając tylko podstawowego “grida” i jQuery.

Pierwsza część serii wywołała niemałą burzę wśród doświadczonych frontendowców. Od początku zdawałem sobie sprawę, że tym kontrowersyjnym mogę tematem obudzić kilka osób z zimowo-wiosennego snu… Podsumowując: udowodniłem, że można ale… chyba nie ma sensu.

Linki do kodu i demo

Klasycznie zamieszczam linki do wersji demonstracyjnej omawianego przykładu oraz do kodu źródłowego na GiHubie:


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