Przejdź do głównej treści
INF.03-08-24.01-SGStyczeń 2024 · 35 kroków · ok. 71 min · 37 kryteriów z klucza

Rozwiązanie krok po kroku: Salon fryzjerski w XAMPP (Nowoczesny kod (grid, JS w pliku))

To drugi sposób rozwiązania tego samego arkusza (wydanego też pod numerem 12 tej sesji). Wynik jest ten sam - baza fryzjer z czterema zapytaniami, dwa przeskalowane zdjęcia i strony index.html oraz fryzura.html z cennikiem i kalkulatorem promocji - i tak samo spełnia każde kryterium klucza. Inna jest droga:

  • siatka CSS zamiast float i clear: <body> ma dwie kolumny 72% i 28% (klucz wprost dopuszcza szerokości w grid-template-columns), bloki lewe i prawe stoją w dwóch pojemnikach-kolumnach, a kod HTML ma naturalną kolejność - najpierw trzy bloki lewe, potem dwa prawe, bez przeplatania ich pod float,
  • zmienne CSS dla kolorów z arkusza, pola radio w etykietach, oznaczone jako jedna grupa dla czytnika ekranu,
  • skrypt w osobnym pliku promocja.js z defer, z obsługą zdarzenia przez addEventListener, cenami z Tabeli 1 w jednym obiekcie i stałą rabatu,
  • komunikat zamiast „cena promocyjna: 0”, gdy nie wybrano długości włosów,
  • w SQL-u IN zamiast OR i aliasy kolumn wynikowych oraz tabel.

Na końcu krótkie porównanie z wersją podstawową (zakładka obok). Baza i grafiki pochodzą z prawdziwego archiwum materialy8, zapytania są policzone na MariaDB, a skrypt sprawdzony w prawdziwej przeglądarce dla każdej długości włosów i bez wyboru; w podglądzie strony fryzura.html można wybierać pola i klikać „Odkryj promocję”.

Jak liczą się punkty. Klucz ma 37 kryteriów (R.1.1 - R.5.6), każde za 1 punkt. Próg zdania to 75%, czyli 28 punktów. Przy każdym kroku jest napisane, które kryteria spełnia.

  1. Etap 1: Baza danych

    Kroki 1-7 · po tym etapie masz 6 z 37 kryteriów (pkt)

    Krok 1: Baza danych fryzjer

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych fryzjer czynność udokumentowano plikiem o nazwie import w formacie PNG

    ok. 2 min
    Polecenie z arkusza

    Utwórz bazę danych o nazwie fryzjer.

    Rozpakuj materialy8.7z z pulpitu (hasło XSaloon[Fryz] - dwa wielkie S, nawiasy kwadratowe) do folderu z numerem zdającego: egzamin2.sql, obraz1.jpg i obraz2.jpg. W phpMyAdmin Nowa → fryzjer albo zapytaniem:

    CREATE DATABASE fryzjer CHARACTER SET utf8 COLLATE utf8_polish_ci;
    
  2. Krok 2: Import tabel z pliku egzamin2.sql

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych fryzjer czynność udokumentowano plikiem o nazwie import w formacie PNG

    ok. 2 min
    Polecenie z arkusza

    Do bazy fryzjer zaimportuj tabele z pliku egzamin2.sql z rozpakowanego archiwum.

    Import → egzamin2.sql. W zadaniu potrzebne są dwie tabele z obrazu 1: uslugi (rodzaj: 1 - kosmetyczne, 2 - fryzjerskie, 3 - inne, oraz klucz obcy kadra_id) i kadra (pracownicy).

  3. Krok 3: Zrzut ekranu import.png

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych fryzjer czynność udokumentowano plikiem o nazwie import w formacie PNG

    ok. 2 min
    Polecenie z arkusza

    Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w formacie PNG pod nazwą import. Nie kadruj zrzutu. Zrzut powinien obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel.

    Zrzut importu w PNG (import.png), a zrzuty zapytań w JPEG (kw1.jpg - kw4.jpg) z widoczną treścią zapytania. Każde zapytanie skopiuj też do kwerendy.txt.

    Typowe błędy

    Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany.

  4. Krok 4: Zapytanie 1: fryzjerzy i styliści

    Kryteria: ,

    R.1.2 Zapisano plik kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania

    R.1.3 Wykonano zapytanie 1 wybierające jedynie pola imie, nazwisko, stanowisko z tabeli kadra dla pracowników na stanowisku fryzjer albo stylista. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko, stanowisko FROM kadra WHERE stanowisko = "fryzjer" OR stanowisko = "stylista"; oraz wynik działania udokumentowano zrzutem, na którym widoczne są jedynie dane: Aleksandra Wilk stylista, Katarzyna Nowak fryzjer

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie pola imie, nazwisko, stanowisko z tabeli kadra dla pracowników na stanowisku fryzjer albo stylista.

    stanowisko IN ('fryzjer', 'stylista') - „jedna z wartości z listy”: to samo co dwa porównania połączone OR, ale krócej i bez powtarzania nazwy kolumny; kolejne stanowisko dopisuje się do listy. Każda klauzula w osobnej linii. Wynik: dwie osoby - Aleksandra Wilk (stylista) i Katarzyna Nowak (fryzjer). Zrzut kw1.jpg.

    Typowe błędy

    AND zamiast OR (albo zamiast IN) szuka osoby, która jest jednocześnie fryzjerem i stylistą - wynik jest pusty.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT imie, nazwisko, stanowisko
    FROM kadra
    WHERE stanowisko IN ('fryzjer', 'stylista');
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: liczba i najwyższa cena usług fryzjerskich

    Kryteria:

    R.1.4 Wykonano zapytanie 2 jedynie dla usług fryzjerskich zliczające liczbę rekordów w tabeli uslugi oraz wskazujące najwyższą cenę usługi. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT COUNT(*), MAX(cena) FROM uslugi WHERE rodzaj = 2; oraz wynik działania udokumentowano zrzutem, na którym widoczne są liczby 3 i 50

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: liczące liczbę usług fryzjerskich oraz wskazujące najwyższą cenę usług fryzjerskich.

    COUNT(*) liczy wiersze, MAX(cena) daje największą cenę, WHERE rodzaj = 2 - usługi fryzjerskie. Aliasy liczba_uslug i najwyzsza_cena nadają kolumnom wyniku czytelne nazwy zamiast COUNT(*). Wynik: 3 i 50. Zrzut kw2.jpg.

    kwerendy.txt Tekst zmienione: 5 linii
    -- Zapytanie 1
    SELECT imie, nazwisko, stanowisko
    FROM kadra
    WHERE stanowisko IN ('fryzjer', 'stylista');
    
    -- Zapytanie 2
    SELECT COUNT(*) AS liczba_uslug, MAX(cena) AS najwyzsza_cena
    FROM uslugi
    WHERE rodzaj = 2;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: usługi z imieniem pracownika

    Kryteria:

    R.1.5 Wykonano zapytanie 3 wybierające nazwy usług oraz przypisane do nich imiona osób z tabeli kadra dla rodzaju usług: fryzjerskie albo inne. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, imie FROM uslugi JOIN kadra ON kadra_id = kadra.id WHERE rodzaj > 1; (możliwe też INNER JOIN lub porównanie kluczy po WHERE, poprawny też warunek: rodzaj = 2 OR rodzaj = 3) oraz wynik działania udokumentowano zrzutem, na którym widoczne jest dokładnie 5 rekordów, dane: Ustalenie diety, Anna; Farbowanie, Katarzyna; Strzyzenie, Katarzyna; Czesanie, Katarzyna; Masaz twarzy, Piotr

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 3: wybierające nazwy usług oraz przypisane do nich imiona osób z tabeli kadra dla rodzaju usług: fryzjerskie albo inne, należy posłużyć się relacją.

    • aliasy tabel u (uslugi) i k (kadra) - obie mają kolumnę id, a przedrostek mówi, której tabeli dotyczy pole,
    • JOIN kadra AS k ON k.id = u.kadra_id - relacja z obrazu 1,
    • u.rodzaj IN (2, 3) - fryzjerskie albo inne.

    Wynik: 5 usług - Ustalenie diety (Anna), Farbowanie, Strzyżenie i Czesanie (Katarzyna), Masaż twarzy (Piotr). Zrzut kw3.jpg.

    Typowe błędy

    ON kadra_id = id bez nazwy albo aliasu tabeli przy id daje błąd „kolumna niejednoznaczna”.

    kwerendy.txt Tekst zmienione: 6 linii
    -- Zapytanie 1
    SELECT imie, nazwisko, stanowisko
    FROM kadra
    WHERE stanowisko IN ('fryzjer', 'stylista');
    
    -- Zapytanie 2
    SELECT COUNT(*) AS liczba_uslug, MAX(cena) AS najwyzsza_cena
    FROM uslugi
    WHERE rodzaj = 2;
    
    -- Zapytanie 3
    SELECT u.nazwa, k.imie
    FROM uslugi AS u
    JOIN kadra AS k ON k.id = u.kadra_id
    WHERE u.rodzaj IN (2, 3);
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: kolumna opinia

    Kryteria:

    R.1.6 Wykonano zapytanie 4 dodające kolumnę do tabeli uslugi o nazwie opinia typu napisowego . W pliku z kwerendami lub na zrzucie istnieje zapis np.: ALTER TABLE uslugi ADD opinia TEXT; (lub ADD COLUMN, dowolny typ napisowy) oraz wynik działania udokumentowano zrzutem, na którym widoczny jest komunikat o poprawnym wykonaniu zapytania lub tabela z dodaną kolumną

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: dodające kolumnę do tabeli uslugi o nazwie opinia typu napisowego.

    ALTER TABLE ... ADD opinia TEXT dopisuje kolumnę tekstową na końcu tabeli; istniejące wiersze dostają w niej NULL. Wykonaj raz - drugi raz baza zgłosi, że kolumna już istnieje. Zrzut kw4.jpg - komunikat albo struktura tabeli.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko, stanowisko
    FROM kadra
    WHERE stanowisko IN ('fryzjer', 'stylista');
    
    -- Zapytanie 2
    SELECT COUNT(*) AS liczba_uslug, MAX(cena) AS najwyzsza_cena
    FROM uslugi
    WHERE rodzaj = 2;
    
    -- Zapytanie 3
    SELECT u.nazwa, k.imie
    FROM uslugi AS u
    JOIN kadra AS k ON k.id = u.kadra_id
    WHERE u.rodzaj IN (2, 3);
    
    -- Zapytanie 4
    ALTER TABLE uslugi ADD opinia TEXT;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strony HTML

    Kroki 8-21 · po tym etapie masz 19 z 37 kryteriów (pkt)

    Krok 8: Obrazy: szerokość 250 i 650 px

    Kryteria:

    R.2.1 Przynajmniej jedną grafikę przeskalowano z zachowaniem proporcji. Wymiary dla obraz1.jpg szerokość 250 px i odpowiadająca temu wysokość 313 px (± 5 px) lub obraz2.jpg szerokość 650 px i odpowiadająca temu wysokość 283 px (± 5 px)

    ok. 3 min
    Polecenie z arkusza

    Plik obraz1.jpg, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji tak, aby jego szerokość wynosiła dokładnie 250 px. Plik obraz2.jpg, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji tak, aby jego szerokość wynosiła dokładnie 650 px.

    Grafiki są takie same jak w wersji podstawowej. W GIMP-ie Obraz → Skaluj obraz z zamkniętym łańcuchem: obraz1.jpg - szerokość 250 (wysokość 313 px), obraz2.jpg - szerokość 650 (wysokość 283 px), jak w kluczu (±5 px).

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Krok 9: Plik index.html: HTML5, język, kodowanie

    Kryteria:

    R.2.2 Witrynę internetową zapisano w plikach index.html i fryzura.html oraz na stronie zastosowano deklarację języka HTML5 <!DOCTYPE html>, zadeklarowano język witryny polski np. <html lang = "pl"> oraz zapisano jawnie właściwy standard kodowania polskich znaków

    ok. 2 min
    Polecenie z arkusza

    Cechy witryny: Składa się ze stron o nazwach index.html oraz fryzura.html. Obie strony różnią się jedynie drugim blokiem lewym. Strony index.html i fryzura.html zapisane w języku HTML 5. Ustawiony język zawartości stron na polski. Jawnie zastosowany właściwy standard kodowania polskich znaków.

    <!DOCTYPE html>, <html lang="pl"> i <meta charset="UTF-8"> - razem R.2.2. Zbuduj w całości index.html, a fryzura.html powstanie z jej kopii z innym drugim blokiem lewym.

    index.html HTML nowy plik
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  10. Krok 10: Tytuł strony

    Kryteria:

    R.2.3 Stronie nadano tytuł: "Fryzjerstwo"

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Fryzjerstwo”.

    <title> (R.2.3) i viewport - telefon nie pomniejsza strony do rozmiaru ekranu komputera.

    index.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  11. Krok 11: Podpięcie arkusza stylów

    Kryteria:

    R.3.6 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl8.css , formatowanie CSS pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy zdający źle przypisał co najmniej jeden selektor do bloku (np. kropka zamiast #)

    ok. 1 min
    Polecenie z arkusza

    Arkusz stylów w pliku o nazwie styl8.css prawidłowo połączony z kodem strony.

    Nazwa z cyfrą: styl8.css. Całe formatowanie pochodzi z tego pliku (R.3.6).

    Typowe błędy

    styl.css bez ósemki odcina wszystkie style (R.3.6).

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
        <link rel="stylesheet" href="styl8.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  12. Krok 12: Bloki strony w dwóch kolumnach

    Kryteria:

    R.2.4 Układ strony zdefiniowano dzieląc ją na bloki: trzy lewe, dwa prawe i stopkę. Zastosowano znaczniki sekcji

    ok. 3 min
    Polecenie z arkusza

    Podział strony na bloki: trzy bloki po lewej stronie i dwa po prawej, poniżej stopka. Podział zrealizowany za pomocą znaczników sekcji tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z Obrazem 2.

    Pięć bloków <section> i <footer> (R.2.4). Bloki lewe i prawe mają różne wysokości, więc każda kolumna dostaje własny pojemnik <div> - siatka postawi pojemniki obok siebie, a bloki ułożą się w nich jeden pod drugim. Dzięki temu kod ma naturalną kolejność: trzy bloki lewe, potem dwa prawe. Wersja z float musiała je przeplatać (lewy, prawy, lewy, prawy, lewy), bo element pływający nie stanie wyżej niż poprzedni.

    Identyfikatory mówią, co jest w bloku: brand (nazwa salonu), feature (zdjęcie albo promocja - jedyny blok, którym różnią się strony), welcome (powitanie i kontakt), prices (cennik), staff (fryzjerka). <div> to tylko pojemnik układu - sekcjami są bloki.

    index.html HTML zmienione: 16 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
        <link rel="stylesheet" href="styl8.css">
    </head>
    <body>
        <div class="column-left">
            <section id="brand">
            </section>
            <section id="feature">
            </section>
            <section id="welcome">
            </section>
        </div>
        <div class="column-right">
            <section id="prices">
            </section>
            <section id="staff">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  13. Krok 13: Pierwszy blok lewy: nagłówek-odnośnik

    Kryteria:

    R.3.3 Po wybraniu odnośnika "SALON FRYZJERSKI" otwiera się strona index.html

    ok. 1 min
    Polecenie z arkusza

    Zawartość pierwszego bloku po lewej stronie: Nagłówek pierwszego stopnia o treści „SALON FRYZJERSKI”, który jest odnośnikiem do strony index.html.

    Odnośnik stoi wewnątrz nagłówka: <h1><a href="index.html">...</a></h1> - nagłówek zostaje nagłówkiem, a jego tekst da się kliknąć (R.3.3).

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
        <link rel="stylesheet" href="styl8.css">
    </head>
    <body>
        <div class="column-left">
            <section id="brand">
                <h1><a href="index.html">SALON FRYZJERSKI</a></h1>
            </section>
            <section id="feature">
            </section>
            <section id="welcome">
            </section>
        </div>
        <div class="column-right">
            <section id="prices">
            </section>
            <section id="staff">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  14. Krok 14: Pierwszy blok prawy: cennik

    Kryteria: , ,

    R.2.6 Na stronie umieszczono tabelę o 5 wierszach i 2 kolumnach, zastosowano znaczniki <table>, <tr>, <td>

    R.2.7 Pierwszy wiersz tabeli zawiera komórki nagłówkowe, zastosowano znaczniki <tr>, <th>

    R.3.2 Po wybraniu odnośnika "Ceny strzyżenia" otwiera się strona fryzura.html

    ok. 3 min
    Polecenie z arkusza

    Zawartość pierwszego bloku po prawej stronie: Nagłówek czwartego stopnia o treści „Ceny strzyżenia”, który jest odnośnikiem do strony fryzura.html. Tabela o pięciu wierszach i dwóch kolumnach, w pierwszym wierszu znajdują się komórki nagłówkowe. Tabela jest zgodna z Tabelą 1 arkusza egzaminacyjnego.

    <h4> z odnośnikiem do strony promocji (R.3.2) i tabela z Tabeli 1: pięć wierszy, dwie kolumny (R.2.6), w pierwszym komórki nagłówkowe <th> (R.2.7).

    • <thead> i <tbody> oddzielają wiersz nagłówkowy od danych - przeglądarka i czytnik ekranu wiedzą, który wiersz opisuje kolumny,
    • scope="col" - komórka nagłówkowa dotyczy całej kolumny pod nią.

    Wiersze <tr> i komórki <td> zostają, tylko podzielone na dwie grupy.

    index.html HTML zmienione: 27 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
        <link rel="stylesheet" href="styl8.css">
    </head>
    <body>
        <div class="column-left">
            <section id="brand">
                <h1><a href="index.html">SALON FRYZJERSKI</a></h1>
            </section>
            <section id="feature">
            </section>
            <section id="welcome">
            </section>
        </div>
        <div class="column-right">
            <section id="prices">
                <h4><a href="fryzura.html">Ceny strzyżenia</a></h4>
                <table>
                    <thead>
                        <tr>
                            <th scope="col">Długość włosów</th>
                            <th scope="col">Cena</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>Krótkie</td>
                            <td>25</td>
                        </tr>
                        <tr>
                            <td>Średnie</td>
                            <td>30</td>
                        </tr>
                        <tr>
                            <td>Półdługie</td>
                            <td>40</td>
                        </tr>
                        <tr>
                            <td>Długie</td>
                            <td>50</td>
                        </tr>
                    </tbody>
                </table>
            </section>
            <section id="staff">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  15. Krok 15: Drugi blok prawy: zdjęcie fryzjerki

    Kryteria:

    R.2.8 Umieszczono co najmniej jedną grafikę: obraz1.jpg z tekstem alternatywnym "Fryzjerka" w bloku drugim prawym lub obraz2.jpg z tekstem alternatywnym "Strzyżenie" w bloku drugim lewym

    ok. 1 min
    Polecenie z arkusza

    Zawartość drugiego bloku po prawej stronie: Obraz o nazwie obraz1.jpg z tekstem alternatywnym „Fryzjerka”.

    Obraz z tekstem alternatywnym z arkusza (R.2.8).

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
        <link rel="stylesheet" href="styl8.css">
    </head>
    <body>
        <div class="column-left">
            <section id="brand">
                <h1><a href="index.html">SALON FRYZJERSKI</a></h1>
            </section>
            <section id="feature">
            </section>
            <section id="welcome">
            </section>
        </div>
        <div class="column-right">
            <section id="prices">
                <h4><a href="fryzura.html">Ceny strzyżenia</a></h4>
                <table>
                    <thead>
                        <tr>
                            <th scope="col">Długość włosów</th>
                            <th scope="col">Cena</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>Krótkie</td>
                            <td>25</td>
                        </tr>
                        <tr>
                            <td>Średnie</td>
                            <td>30</td>
                        </tr>
                        <tr>
                            <td>Półdługie</td>
                            <td>40</td>
                        </tr>
                        <tr>
                            <td>Długie</td>
                            <td>50</td>
                        </tr>
                    </tbody>
                </table>
            </section>
            <section id="staff">
                <img src="obraz1.jpg" alt="Fryzjerka">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  16. Krok 16: Trzeci blok lewy: powitanie i kontakt

    ok. 1 min
    Polecenie z arkusza

    Zawartość trzeciego bloku po lewej stronie: Akapit (paragraf) o treści: „Witaj! Miło nam, że odwiedziłeś nasz salon. Sprawdź promocje!”. Nagłówek czwartego stopnia o treści „Kontakt: 444 555 666”.

    Akapit i <h4>.

    index.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
        <link rel="stylesheet" href="styl8.css">
    </head>
    <body>
        <div class="column-left">
            <section id="brand">
                <h1><a href="index.html">SALON FRYZJERSKI</a></h1>
            </section>
            <section id="feature">
            </section>
            <section id="welcome">
                <p>Witaj! Miło nam, że odwiedziłeś nasz salon. Sprawdź promocje!</p>
                <h4>Kontakt: 444 555 666</h4>
            </section>
        </div>
        <div class="column-right">
            <section id="prices">
                <h4><a href="fryzura.html">Ceny strzyżenia</a></h4>
                <table>
                    <thead>
                        <tr>
                            <th scope="col">Długość włosów</th>
                            <th scope="col">Cena</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>Krótkie</td>
                            <td>25</td>
                        </tr>
                        <tr>
                            <td>Średnie</td>
                            <td>30</td>
                        </tr>
                        <tr>
                            <td>Półdługie</td>
                            <td>40</td>
                        </tr>
                        <tr>
                            <td>Długie</td>
                            <td>50</td>
                        </tr>
                    </tbody>
                </table>
            </section>
            <section id="staff">
                <img src="obraz1.jpg" alt="Fryzjerka">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  17. Krok 17: Stopka

    Kryteria:

    R.2.5 W bloku pierwszym lewym zapisano nagłówek h1: "SALON FRYZJERSKI", w pierwszym prawym h4: "Ceny strzyżenia" oraz w trzecim lewym h4: "Kontakt: 444 555 666" oraz przynajmniej jeden paragraf

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: Akapit (paragraf) o treści „Autor: ”, dalej wstawiony numer zdającego.

    Na egzaminie po „Autor:” wpisujesz swój numer zdającego (PESEL), tu stoi autor rozwiązania. Z <h1> i oboma <h4> to komplet do R.2.5.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
        <link rel="stylesheet" href="styl8.css">
    </head>
    <body>
        <div class="column-left">
            <section id="brand">
                <h1><a href="index.html">SALON FRYZJERSKI</a></h1>
            </section>
            <section id="feature">
            </section>
            <section id="welcome">
                <p>Witaj! Miło nam, że odwiedziłeś nasz salon. Sprawdź promocje!</p>
                <h4>Kontakt: 444 555 666</h4>
            </section>
        </div>
        <div class="column-right">
            <section id="prices">
                <h4><a href="fryzura.html">Ceny strzyżenia</a></h4>
                <table>
                    <thead>
                        <tr>
                            <th scope="col">Długość włosów</th>
                            <th scope="col">Cena</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>Krótkie</td>
                            <td>25</td>
                        </tr>
                        <tr>
                            <td>Średnie</td>
                            <td>30</td>
                        </tr>
                        <tr>
                            <td>Półdługie</td>
                            <td>40</td>
                        </tr>
                        <tr>
                            <td>Długie</td>
                            <td>50</td>
                        </tr>
                    </tbody>
                </table>
            </section>
            <section id="staff">
                <img src="obraz1.jpg" alt="Fryzjerka">
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  18. Krok 18: Drugi blok lewy strony głównej

    ok. 1 min
    Polecenie z arkusza

    Zawartość drugiego bloku po lewej stronie dla strony index.html: Obraz o nazwie obraz2.jpg z tekstem alternatywnym „Strzyżenie”.

    Obraz z tekstem alternatywnym. Strona główna jest gotowa.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
        <link rel="stylesheet" href="styl8.css">
    </head>
    <body>
        <div class="column-left">
            <section id="brand">
                <h1><a href="index.html">SALON FRYZJERSKI</a></h1>
            </section>
            <section id="feature">
                <img src="obraz2.jpg" alt="Strzyżenie">
            </section>
            <section id="welcome">
                <p>Witaj! Miło nam, że odwiedziłeś nasz salon. Sprawdź promocje!</p>
                <h4>Kontakt: 444 555 666</h4>
            </section>
        </div>
        <div class="column-right">
            <section id="prices">
                <h4><a href="fryzura.html">Ceny strzyżenia</a></h4>
                <table>
                    <thead>
                        <tr>
                            <th scope="col">Długość włosów</th>
                            <th scope="col">Cena</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>Krótkie</td>
                            <td>25</td>
                        </tr>
                        <tr>
                            <td>Średnie</td>
                            <td>30</td>
                        </tr>
                        <tr>
                            <td>Półdługie</td>
                            <td>40</td>
                        </tr>
                        <tr>
                            <td>Długie</td>
                            <td>50</td>
                        </tr>
                    </tbody>
                </table>
            </section>
            <section id="staff">
                <img src="obraz1.jpg" alt="Fryzjerka">
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  19. Krok 19: Strona fryzura.html z kopii

    ok. 2 min
    Polecenie z arkusza

    Zawartość drugiego bloku po lewej stronie dla strony fryzura.html (Obraz 3): Nagłówek drugiego stopnia o treści „PROMOCJA!”.

    Zapisz jako fryzura.html z kopii strony głównej - wymieniasz tylko zawartość bloku feature.

    fryzura.html HTML nowy plik
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
        <link rel="stylesheet" href="styl8.css">
    </head>
    <body>
        <div class="column-left">
            <section id="brand">
                <h1><a href="index.html">SALON FRYZJERSKI</a></h1>
            </section>
            <section id="feature">
                <h2>PROMOCJA!</h2>
            </section>
            <section id="welcome">
                <p>Witaj! Miło nam, że odwiedziłeś nasz salon. Sprawdź promocje!</p>
                <h4>Kontakt: 444 555 666</h4>
            </section>
        </div>
        <div class="column-right">
            <section id="prices">
                <h4><a href="fryzura.html">Ceny strzyżenia</a></h4>
                <table>
                    <thead>
                        <tr>
                            <th scope="col">Długość włosów</th>
                            <th scope="col">Cena</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>Krótkie</td>
                            <td>25</td>
                        </tr>
                        <tr>
                            <td>Średnie</td>
                            <td>30</td>
                        </tr>
                        <tr>
                            <td>Półdługie</td>
                            <td>40</td>
                        </tr>
                        <tr>
                            <td>Długie</td>
                            <td>50</td>
                        </tr>
                    </tbody>
                </table>
            </section>
            <section id="staff">
                <img src="obraz1.jpg" alt="Fryzjerka">
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (fryzura.html)
  20. Krok 20: Cztery pola radio w grupie

    Kryteria:

    R.3.5 W jednym momencie można wybrać tylko jeden przycisk radio

    ok. 3 min
    Polecenie z arkusza

    Cztery pola radio, jedno pod drugim, z podpisami: Krótkie, Średnie, Półdługie, Długie. W danym momencie tylko jedno pole radio może być zaznaczone.

    • wspólne name="length" - przeglądarka traktuje cztery pola jako jedną grupę i pozwala zaznaczyć tylko jedno (R.3.5),
    • value - wartość pola (short, medium...) odczyta skrypt; identyfikatory nie są potrzebne,
    • <label> obejmujący pole - kliknięcie podpisu zaznacza pole, a czytnik ekranu odczyta podpis razem z polem,
    • role="radiogroup" z aria-label - czytnik ekranu zapowie grupę „Długość włosów”.

    Pola stoją na razie w jednej linii - jedno pod drugim ustawi je CSS, bez <br>.

    Typowe błędy

    Różne name w każdym polu pozwalają zaznaczyć kilka naraz - R.3.5 nie jest spełnione.

    fryzura.html HTML zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
        <link rel="stylesheet" href="styl8.css">
    </head>
    <body>
        <div class="column-left">
            <section id="brand">
                <h1><a href="index.html">SALON FRYZJERSKI</a></h1>
            </section>
            <section id="feature">
                <h2>PROMOCJA!</h2>
                <div role="radiogroup" aria-label="Długość włosów">
                    <label><input type="radio" name="length" value="short"> Krótkie</label>
                    <label><input type="radio" name="length" value="medium"> Średnie</label>
                    <label><input type="radio" name="length" value="halflong"> Półdługie</label>
                    <label><input type="radio" name="length" value="long"> Długie</label>
                </div>
            </section>
            <section id="welcome">
                <p>Witaj! Miło nam, że odwiedziłeś nasz salon. Sprawdź promocje!</p>
                <h4>Kontakt: 444 555 666</h4>
            </section>
        </div>
        <div class="column-right">
            <section id="prices">
                <h4><a href="fryzura.html">Ceny strzyżenia</a></h4>
                <table>
                    <thead>
                        <tr>
                            <th scope="col">Długość włosów</th>
                            <th scope="col">Cena</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>Krótkie</td>
                            <td>25</td>
                        </tr>
                        <tr>
                            <td>Średnie</td>
                            <td>30</td>
                        </tr>
                        <tr>
                            <td>Półdługie</td>
                            <td>40</td>
                        </tr>
                        <tr>
                            <td>Długie</td>
                            <td>50</td>
                        </tr>
                    </tbody>
                </table>
            </section>
            <section id="staff">
                <img src="obraz1.jpg" alt="Fryzjerka">
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (fryzura.html)
  21. Krok 21: Przycisk i akapit na wynik

    Kryteria:

    R.2.9 Na stronie fryzura.html umieszczono cztery kontrolki radio z opisami: Krótkie, Średnie, Półdługie, Długie oraz jeden przycisk "Odkryj promocję"

    ok. 1 min
    Polecenie z arkusza

    Poniżej przycisk o treści „Odkryj promocję”, którego wciśnięcie powoduje wykonanie skryptu.

    Przycisk z identyfikatorem - zdarzenie podepnie skrypt (bez atrybutu onclick w HTML-u). type="button" mówi wprost, że przycisk niczego nie wysyła. Pusty <p id="result"> przyjmie wynik; aria-live="polite" - czytnik ekranu przeczyta nowy tekst sam, bez szukania go na stronie. Pola i przycisk to komplet do R.2.9.

    fryzura.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
        <link rel="stylesheet" href="styl8.css">
    </head>
    <body>
        <div class="column-left">
            <section id="brand">
                <h1><a href="index.html">SALON FRYZJERSKI</a></h1>
            </section>
            <section id="feature">
                <h2>PROMOCJA!</h2>
                <div role="radiogroup" aria-label="Długość włosów">
                    <label><input type="radio" name="length" value="short"> Krótkie</label>
                    <label><input type="radio" name="length" value="medium"> Średnie</label>
                    <label><input type="radio" name="length" value="halflong"> Półdługie</label>
                    <label><input type="radio" name="length" value="long"> Długie</label>
                </div>
                <button type="button" id="discover">Odkryj promocję</button>
                <p id="result" aria-live="polite"></p>
            </section>
            <section id="welcome">
                <p>Witaj! Miło nam, że odwiedziłeś nasz salon. Sprawdź promocje!</p>
                <h4>Kontakt: 444 555 666</h4>
            </section>
        </div>
        <div class="column-right">
            <section id="prices">
                <h4><a href="fryzura.html">Ceny strzyżenia</a></h4>
                <table>
                    <thead>
                        <tr>
                            <th scope="col">Długość włosów</th>
                            <th scope="col">Cena</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>Krótkie</td>
                            <td>25</td>
                        </tr>
                        <tr>
                            <td>Średnie</td>
                            <td>30</td>
                        </tr>
                        <tr>
                            <td>Półdługie</td>
                            <td>40</td>
                        </tr>
                        <tr>
                            <td>Długie</td>
                            <td>50</td>
                        </tr>
                    </tbody>
                </table>
            </section>
            <section id="staff">
                <img src="obraz1.jpg" alt="Fryzjerka">
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (fryzura.html)
  22. Etap 3: Styl CSS

    Kroki 22-29 · po tym etapie masz 30 z 37 kryteriów (pkt)

    Krok 22: Plik styl8.css: zmienne, krój i wyśrodkowanie

    Kryteria:

    R.4.1 Ustawiono domyślne formatowanie wszystkich selektorów (*): krój czcionki Garamond, wyrównanie tekstu do środka

    ok. 2 min
    Polecenie z arkusza

    Ustawione domyślne wartości dla wszystkich selektorów stylu CSS: krój czcionki Garamond, wyrównanie tekstu do środka.

    Kolory z arkusza w zmiennych - #795548 pojawia się w czterech regułach (blok, stopka, ramka tabeli, tekst bloków prawych). Selektor * z Garamondem i krojem zapasowym serif (R.4.1).

    styl8.css CSS nowy plik
    :root {
        --brown: #795548;
        --beige: #BCAAA4;
        --hover: Sienna;
    }
    
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    Podgląd strony po tym kroku (index.html)
  23. Krok 23: Układ: siatka z dwiema kolumnami

    Kryteria:

    R.3.1 Układ bloków po uruchomieniu przynajmniej jednej strony w przeglądarce jest zgodny z obrazem 2 w arkuszu (prawidłowo zastosowano właściwości CSS decydujące o układzie strony, np. float i clear albo display flex albo grid albo position)

    ok. 4 min
    Polecenie z arkusza

    Podział strony na bloki: trzy bloki po lewej stronie i dwa po prawej, poniżej stopka. Podział zrealizowany za pomocą znaczników sekcji tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z Obrazem 2. Wspólne dla wszystkich bloków lewych: szerokość 72%. Wspólne dla obu prawych bloków: szerokość 28%.

    • grid-template-columns: 72% 28% - dwie kolumny o szerokościach z arkusza; bloki w pojemnikach zajmują całą szerokość swojej kolumny. Klucz wprost uznaje szerokości zapisane w grid-template-columns (R.4.4 - razem z szerokością tabeli w dalszym kroku),
    • grid-template-areas rysuje układ słowami: kolumna lewa i prawa, pod nimi stopka na całą szerokość - bez float i bez clear (R.3.1),
    • align-items: start - kolumny mają własne wysokości, zamiast rozciągać się do wyższej,
    • display: flow-root bloków - margines nagłówka nie „wychodzi” poza blok (np. nad brązowe tło pierwszego bloku); w wersji z float robił to sam float.
    Typowe błędy

    width: 72% dopisane blokom lewym w kolumnie 72% daje bloki szerokie na 52% strony - procent szerokości liczy się tu od kolumny, nie od strony.

    styl8.css CSS zmienione: 25 linii
    :root {
        --brown: #795548;
        --beige: #BCAAA4;
        --hover: Sienna;
    }
    
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    
    body {
        display: grid;
        grid-template-columns: 72% 28%;
        grid-template-areas:
            "left   right"
            "footer footer";
        align-items: start;
    }
    
    .column-left {
        grid-area: left;
    }
    
    .column-right {
        grid-area: right;
    }
    
    footer {
        grid-area: footer;
    }
    
    section {
        display: flow-root;
    }
    Podgląd strony po tym kroku (index.html)
  24. Krok 24: Pierwszy i drugi blok lewy

    ok. 1 min
    Polecenie z arkusza

    Dla pierwszego lewego bloku: kolor tła #795548, rozmiar czcionki 170%. Dla drugiego lewego bloku: wysokość 400 px.

    Tło ze zmiennej i rozmiar czcionki dla #brand, wysokość dla #feature - na obu stronach ten sam blok, raz ze zdjęciem, raz z promocją.

    styl8.css CSS zmienione: 9 linii
    :root {
        --brown: #795548;
        --beige: #BCAAA4;
        --hover: Sienna;
    }
    
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    
    body {
        display: grid;
        grid-template-columns: 72% 28%;
        grid-template-areas:
            "left   right"
            "footer footer";
        align-items: start;
    }
    
    .column-left {
        grid-area: left;
    }
    
    .column-right {
        grid-area: right;
    }
    
    footer {
        grid-area: footer;
    }
    
    section {
        display: flow-root;
    }
    
    #brand {
        background-color: var(--brown);
        font-size: 170%;
    }
    
    #feature {
        height: 400px;
    }
    Podgląd strony po tym kroku (index.html)
  25. Krok 25: Bloki prawe

    Kryteria:

    R.4.5 Ustawiono wysokość 400px dla bloku drugiego lewego oraz obu prawych

    ok. 1 min
    Polecenie z arkusza

    Wspólne dla obu prawych bloków: kolor tła #BCAAA4, kolor czcionki #795548, wysokość 400 px, szerokość 28%.

    Szerokość 28% daje kolumna siatki. Wysokości 400 px: drugi blok lewy i oba prawe (R.4.5).

    styl8.css CSS zmienione: 7 linii
    :root {
        --brown: #795548;
        --beige: #BCAAA4;
        --hover: Sienna;
    }
    
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    
    body {
        display: grid;
        grid-template-columns: 72% 28%;
        grid-template-areas:
            "left   right"
            "footer footer";
        align-items: start;
    }
    
    .column-left {
        grid-area: left;
    }
    
    .column-right {
        grid-area: right;
    }
    
    footer {
        grid-area: footer;
    }
    
    section {
        display: flow-root;
    }
    
    #brand {
        background-color: var(--brown);
        font-size: 170%;
    }
    
    #feature {
        height: 400px;
    }
    
    #prices,
    #staff {
        background-color: var(--beige);
        color: var(--brown);
        height: 400px;
    }
    Podgląd strony po tym kroku (index.html)
  26. Krok 26: Stopka

    Kryteria:

    R.4.2 Ustawiono kolor tła #795548 dla pierwszego bloku lewego i stopki oraz #BCAAA4 dla obu bloków prawych

    ok. 1 min
    Polecenie z arkusza

    Dla stopki: kolor tła #795548, biały kolor czcionki, marginesy wewnętrzne 20 px.

    Drugą regułę footer (z grid-area) można połączyć z tą - przeglądarka i tak składa wszystkie reguły tego samego selektora. Kolory tła są już komplet (R.4.2).

    styl8.css CSS zmienione: 6 linii
    :root {
        --brown: #795548;
        --beige: #BCAAA4;
        --hover: Sienna;
    }
    
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    
    body {
        display: grid;
        grid-template-columns: 72% 28%;
        grid-template-areas:
            "left   right"
            "footer footer";
        align-items: start;
    }
    
    .column-left {
        grid-area: left;
    }
    
    .column-right {
        grid-area: right;
    }
    
    footer {
        grid-area: footer;
    }
    
    section {
        display: flow-root;
    }
    
    #brand {
        background-color: var(--brown);
        font-size: 170%;
    }
    
    #feature {
        height: 400px;
    }
    
    #prices,
    #staff {
        background-color: var(--beige);
        color: var(--brown);
        height: 400px;
    }
    
    footer {
        background-color: var(--brown);
        color: white;
        padding: 20px;
    }
    Podgląd strony po tym kroku (index.html)
  27. Krok 27: Tabela i wiersz po wskazaniu

    Kryteria: , ,

    R.4.4 Ustawiono szerokość 72% dla trzech bloków lewych i 28% dla obu prawych (width lub grid- template-columns lub flex) i 80% dla selektora table

    R.4.7 Ustawiono dla tabeli obramowanie o cechach: 1px solid #795548

    R.4.10 W momencie, gdy kursor znajduje się na wierszu tabeli, jego tło zmienia się na Sienna, a kolor czcionki na biały

    ok. 2 min
    Polecenie z arkusza

    Dla selektora tabeli: marginesy zewnętrzne wyliczane automatycznie przez przeglądarkę, szerokość 80%, obramowanie linią ciągłą o szerokości 1 px i kolorze #795548. W momencie, gdy kursor znajduje się na wierszu tabeli, jego tło zmienia się na Sienna, a kolor czcionki na biały.

    margin: auto wyśrodkowuje tabelę, ramka ze zmiennej (R.4.7). tr:hover podświetla cały wiersz (R.4.10) - także wiersz nagłówkowy, jak w wersji podstawowej; samą treść tabeli łapałby tbody tr:hover, ale klucz opisuje wiersz tabeli ogólnie. Z szerokością tabeli 80% komplet szerokości (R.4.4).

    styl8.css CSS zmienione: 11 linii
    :root {
        --brown: #795548;
        --beige: #BCAAA4;
        --hover: Sienna;
    }
    
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    
    body {
        display: grid;
        grid-template-columns: 72% 28%;
        grid-template-areas:
            "left   right"
            "footer footer";
        align-items: start;
    }
    
    .column-left {
        grid-area: left;
    }
    
    .column-right {
        grid-area: right;
    }
    
    footer {
        grid-area: footer;
    }
    
    section {
        display: flow-root;
    }
    
    #brand {
        background-color: var(--brown);
        font-size: 170%;
    }
    
    #feature {
        height: 400px;
    }
    
    #prices,
    #staff {
        background-color: var(--beige);
        color: var(--brown);
        height: 400px;
    }
    
    footer {
        background-color: var(--brown);
        color: white;
        padding: 20px;
    }
    
    table {
        margin: auto;
        width: 80%;
        border: 1px solid var(--brown);
    }
    
    tr:hover {
        background-color: var(--hover);
        color: white;
    }
    Podgląd strony po tym kroku (index.html)
  28. Krok 28: Nagłówki, obrazy, odnośniki

    Kryteria: , ,

    R.4.3 Ustawiono biały kolor czcionki dla stopki i selektora a oraz #795548 dla obu bloków prawych

    R.4.8 Ustawiono rozmiar czcionki 170% dla pierwszego lewego bloku oraz 200% dla selektora h4

    R.4.9 Ustawiono dla obrazu zaokrąglenie rogów 40px (border-radius)

    ok. 2 min
    Polecenie z arkusza

    Dla selektora nagłówka czwartego stopnia: rozmiar czcionki 200%. Dla selektora obrazu: marginesy wewnętrzne 20 px, zaokrąglenie rogów 40 px. Dla selektora odnośnika: biały kolor czcionki.

    Selektory znaczników h4, img, a - uwaga arkusza wyklucza klasy i identyfikatory. Rozmiary czcionek (R.4.8), zaokrąglenie (R.4.9), białe odnośniki razem z białą stopką i kolorem bloków prawych (R.4.3).

    Typowe błędy

    #prices h4 albo klasa nagłówka nie spełnia R.4.8 - klucz wymaga samego selektora h4.

    styl8.css CSS zmienione: 13 linii
    :root {
        --brown: #795548;
        --beige: #BCAAA4;
        --hover: Sienna;
    }
    
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    
    body {
        display: grid;
        grid-template-columns: 72% 28%;
        grid-template-areas:
            "left   right"
            "footer footer";
        align-items: start;
    }
    
    .column-left {
        grid-area: left;
    }
    
    .column-right {
        grid-area: right;
    }
    
    footer {
        grid-area: footer;
    }
    
    section {
        display: flow-root;
    }
    
    #brand {
        background-color: var(--brown);
        font-size: 170%;
    }
    
    #feature {
        height: 400px;
    }
    
    #prices,
    #staff {
        background-color: var(--beige);
        color: var(--brown);
        height: 400px;
    }
    
    footer {
        background-color: var(--brown);
        color: white;
        padding: 20px;
    }
    
    table {
        margin: auto;
        width: 80%;
        border: 1px solid var(--brown);
    }
    
    tr:hover {
        background-color: var(--hover);
        color: white;
    }
    
    h4 {
        font-size: 200%;
    }
    
    img {
        padding: 20px;
        border-radius: 40px;
    }
    
    a {
        color: white;
    }
    Podgląd strony po tym kroku (index.html)
  29. Krok 29: Pola radio jedno pod drugim

    Kryteria:

    R.4.6 Ustawiono marginesy wewnętrzne (padding) 20px dla stopki i selektora img oraz marginesy zewnętrzne (margin) 7px dla pola radio i margin: auto dla tabeli (dla pól radio wszystkie rozwiązania są prawidłowe oprócz zastosowania tego samego id dla wszystkich pól)

    ok. 1 min
    Polecenie z arkusza

    Dla pola radio: marginesy zewnętrzne 7 px.

    input[type="radio"] - selektor atrybutu: tylko pola radio, nie każde <input>; margines 7 px. Pola z podpisami stoją jedno pod drugim dzięki display: block etykiet w grupie - bez znaczników <br> w HTML-u. Z padding stopki i obrazu oraz margin: auto tabeli to komplet odstępów (R.4.6).

    styl8.css CSS zmienione: 8 linii
    :root {
        --brown: #795548;
        --beige: #BCAAA4;
        --hover: Sienna;
    }
    
    * {
        font-family: Garamond, serif;
        text-align: center;
    }
    
    body {
        display: grid;
        grid-template-columns: 72% 28%;
        grid-template-areas:
            "left   right"
            "footer footer";
        align-items: start;
    }
    
    .column-left {
        grid-area: left;
    }
    
    .column-right {
        grid-area: right;
    }
    
    footer {
        grid-area: footer;
    }
    
    section {
        display: flow-root;
    }
    
    #brand {
        background-color: var(--brown);
        font-size: 170%;
    }
    
    #feature {
        height: 400px;
    }
    
    #prices,
    #staff {
        background-color: var(--beige);
        color: var(--brown);
        height: 400px;
    }
    
    footer {
        background-color: var(--brown);
        color: white;
        padding: 20px;
    }
    
    table {
        margin: auto;
        width: 80%;
        border: 1px solid var(--brown);
    }
    
    tr:hover {
        background-color: var(--hover);
        color: white;
    }
    
    h4 {
        font-size: 200%;
    }
    
    img {
        padding: 20px;
        border-radius: 40px;
    }
    
    a {
        color: white;
    }
    
    input[type="radio"] {
        margin: 7px;
    }
    
    [role="radiogroup"] label {
        display: block;
    }
    Podgląd strony po tym kroku (fryzura.html)
  30. Etap 4: Skrypt JavaScript

    Kroki 30-33 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 30: Plik promocja.js i obsługa kliknięcia

    Kryteria: ,

    R.3.4 Wybranie przycisku powoduje uruchomienie funkcji skryptu (obsługa zdarzenia zdefiniowana np. inline w znaczniku jako atrybut onClick lub w skrypcie JS np.: element.addEventListener("click", funkcja); lub element.onClick = …)

    R.5.1 Skrypt napisano w języku JavaScript i zawiera on co najmniej jedną instrukcję tego języka zapisaną zgodnie ze składnią

    ok. 3 min
    Polecenie z arkusza

    Wymagania dotyczące skryptu: Napisany w języku wykonywanym po stronie przeglądarki. Uruchamia się po wciśnięciu przycisku na stronie fryzura.html.

    Skrypt w osobnym pliku promocja.js (arkusz nie wskazuje, gdzie ma być), dołączony tylko w fryzura.html, bo tylko ona go potrzebuje:

    • defer - przeglądarka pobiera plik równolegle, a wykonuje go dopiero po wczytaniu całego HTML-u, więc getElementById('discover') znajdzie przycisk, choć <script> stoi w <head>,
    • addEventListener('click', showPromotion) - kliknięcie przycisku wywołuje funkcję (R.3.4, klucz wymienia tę formę wprost); HTML zostaje bez kodu JavaScript,
    • const DISCOUNT = 10 - rabat w jednej stałej.

    Funkcja jest na razie pusta (R.5.1).

    fryzura.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Fryzjerstwo</title>
        <link rel="stylesheet" href="styl8.css">
        <script src="promocja.js" defer></script>
    </head>
    <body>
        <div class="column-left">
            <section id="brand">
                <h1><a href="index.html">SALON FRYZJERSKI</a></h1>
            </section>
            <section id="feature">
                <h2>PROMOCJA!</h2>
                <div role="radiogroup" aria-label="Długość włosów">
                    <label><input type="radio" name="length" value="short"> Krótkie</label>
                    <label><input type="radio" name="length" value="medium"> Średnie</label>
                    <label><input type="radio" name="length" value="halflong"> Półdługie</label>
                    <label><input type="radio" name="length" value="long"> Długie</label>
                </div>
                <button type="button" id="discover">Odkryj promocję</button>
                <p id="result" aria-live="polite"></p>
            </section>
            <section id="welcome">
                <p>Witaj! Miło nam, że odwiedziłeś nasz salon. Sprawdź promocje!</p>
                <h4>Kontakt: 444 555 666</h4>
            </section>
        </div>
        <div class="column-right">
            <section id="prices">
                <h4><a href="fryzura.html">Ceny strzyżenia</a></h4>
                <table>
                    <thead>
                        <tr>
                            <th scope="col">Długość włosów</th>
                            <th scope="col">Cena</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>Krótkie</td>
                            <td>25</td>
                        </tr>
                        <tr>
                            <td>Średnie</td>
                            <td>30</td>
                        </tr>
                        <tr>
                            <td>Półdługie</td>
                            <td>40</td>
                        </tr>
                        <tr>
                            <td>Długie</td>
                            <td>50</td>
                        </tr>
                    </tbody>
                </table>
            </section>
            <section id="staff">
                <img src="obraz1.jpg" alt="Fryzjerka">
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    promocja.js JavaScript nowy plik
    const DISCOUNT = 10;    // promocja: 10 zł taniej
    
    function showPromotion() {
    }
    
    document.getElementById('discover').addEventListener('click', showPromotion);
    Podgląd strony po tym kroku (fryzura.html)
  31. Krok 31: Zaznaczone pole i ceny z Tabeli 1

    Kryteria: ,

    R.5.2 Skrypt wykorzystuje przynajmniej jedną metodę DOM

    R.5.3 Skrypt stosuje własność checked do sprawdzenia stanu przynajmniej jednego pola radio

    ok. 3 min
    Polecenie z arkusza

    Na podstawie wybranego przycisku radio wyświetla promocyjną cenę strzyżenia.

    • PRICES - ceny z Tabeli 1 w jednym obiekcie, kluczem jest value pola radio. Cennik jest w kodzie raz, a nie w czterech if,
    • document.querySelectorAll('input[name="length"]') - metoda DOM, która znajduje wszystkie pola grupy (R.5.2),
    • [...radios].find(radio => radio.checked) - z listy pól wybiera to, którego właściwość checked jest true (R.5.3); gdy nic nie zaznaczono, find zwraca undefined.
    promocja.js JavaScript zmienione: 8 linii
    const PRICES = {    // Tabela 1: cena strzyżenia
        short: 25,
        medium: 30,
        halflong: 40,
        long: 50,
    };
    const DISCOUNT = 10;    // promocja: 10 zł taniej
    
    function showPromotion() {
        const radios = document.querySelectorAll('input[name="length"]');
        const selected = [...radios].find(radio => radio.checked);
    }
    
    document.getElementById('discover').addEventListener('click', showPromotion);
    Podgląd strony po tym kroku (fryzura.html)
  32. Krok 32: Cena promocyjna o 10 zł niższa

    Kryteria:

    R.5.4 Skrypt wyznacza cenę promocyjną na podstawie zaznaczonego pola: krótkie 15, średnie 20, półdługie 30, długie 40

    ok. 2 min
    Polecenie z arkusza

    Cena promocyjna jest o 10 zł niższa od ceny strzyżenia zawartej w Tabeli 1.

    PRICES[selected.value] - DISCOUNT - cena z cennika dla zaznaczonej długości minus rabat: 15, 20, 30 albo 40 zł (R.5.4). Gdy nie zaznaczono żadnego pola, funkcja wypisuje „Wybierz długość włosów.” i kończy działanie (return) - zamiast „cena promocyjna: 0” albo błędu.

    promocja.js JavaScript zmienione: 8 linii
    const PRICES = {    // Tabela 1: cena strzyżenia
        short: 25,
        medium: 30,
        halflong: 40,
        long: 50,
    };
    const DISCOUNT = 10;    // promocja: 10 zł taniej
    
    function showPromotion() {
        const radios = document.querySelectorAll('input[name="length"]');
        const selected = [...radios].find(radio => radio.checked);
        const result = document.getElementById('result');
    
        if (selected === undefined) {
            result.textContent = 'Wybierz długość włosów.';
            return;
        }
    
        const promoPrice = PRICES[selected.value] - DISCOUNT;
    }
    
    document.getElementById('discover').addEventListener('click', showPromotion);
    Podgląd strony po tym kroku (fryzura.html)
  33. Krok 33: Wynik pod przyciskiem

    Kryteria: ,

    R.5.5 Skrypt wyświetla wyznaczony wynik w akapicie pod przyciskiem według wzoru: "cena promocyjna: <wartość>” (gdzie <wartość> wyznaczono w R.5.4)

    R.5.6 Zastosowano znaczące nazewnictwo dla wszystkich zmiennych i funkcji w języku polskim lub angielskim. Nazwy odzwierciedlają cel zastosowania

    ok. 2 min
    Polecenie z arkusza

    Wynik działania wyświetla się w akapicie pod przyciskiem według wzoru: „cena promocyjna: <wartość>”, gdzie <wartość> oznacza obliczoną cenę.

    Szablon tekstowy (odwrotne apostrofy i ${...}) wstawia wartość do napisu bez sklejania plusami, a textContent wpisuje zwykły tekst - nie interpretuje go jako HTML (R.5.5). Wybierz w podglądzie „Średnie” i kliknij „Odkryj promocję” - „cena promocyjna: 20”, jak na obrazie 3. Nazwy mówią, co przechowują: PRICES, DISCOUNT, radios, selected, result, promoPrice, showPromotion (R.5.6).

    promocja.js JavaScript zmienione: 1 linia
    const PRICES = {    // Tabela 1: cena strzyżenia
        short: 25,
        medium: 30,
        halflong: 40,
        long: 50,
    };
    const DISCOUNT = 10;    // promocja: 10 zł taniej
    
    function showPromotion() {
        const radios = document.querySelectorAll('input[name="length"]');
        const selected = [...radios].find(radio => radio.checked);
        const result = document.getElementById('result');
    
        if (selected === undefined) {
            result.textContent = 'Wybierz długość włosów.';
            return;
        }
    
        const promoPrice = PRICES[selected.value] - DISCOUNT;
        result.textContent = `cena promocyjna: ${promoPrice}`;
    }
    
    document.getElementById('discover').addEventListener('click', showPromotion);
    Podgląd strony po tym kroku (fryzura.html)
  34. Etap 5: Porównanie z wersją podstawową

    Krok 34 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 34: Co jest inaczej i którą wersję wybrać na egzaminie

    ok. 3 min

    Obie wersje dają komplet 37 punktów. Różnice:

    wersja podstawowawersja nowoczesna
    układfloat i clear lewych i prawych blokówsiatka 72% 28% na <body>, pojemniki kolumn
    kolejność w HTMLprzeplatana: lewy, prawy, lewy, prawy, lewynaturalna: trzy lewe, dwa prawe
    tabelawiersze w <table><thead>, <tbody>, scope="col"
    pola radioid + <label for>, <br><label> wokół pola, value, role="radiogroup", CSS zamiast <br>
    skryptw <script> na końcu fryzura.html, onclickpromocja.js z defer, addEventListener
    cenycztery if z cenami w kodzieobiekt PRICES i stała DISCOUNT
    brak wyboru„cena promocyjna: 0”„Wybierz długość włosów.”
    SQLOR, kolumna COUNT(*)IN, aliasy kolumn i tabel

    Na egzaminie wersja podstawowa używa tylko elementów z tabeli DOM w arkuszu (getElementById, onclick) i łatwiej ją napisać bez dokumentacji. Nowoczesna ma jeden cennik w kodzie i prostszy układ. Obie formy obsługi kliknięcia klucz wymienia wprost.

    Podgląd strony bez zmian - taki jak po kroku 33.

  35. Etap 6: Oddanie pracy

    Krok 35 · po tym etapie masz 37 z 37 kryteriów (pkt)

    Krok 35: Plik przeglądarka.txt i nagranie płyty

    ok. 5 min
    Polecenie z arkusza

    Po zakończeniu pracy utwórz w folderze z numerem zdającego plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowana była poprawność działania witryny. Nagraj płytę z rezultatami pracy.

    W przeglądarka.txt nazwa przeglądarki. W folderze: fryzura.html, import.png, index.html, kw1.jpg - kw4.jpg, kwerendy.txt, obraz1.jpg, obraz2.jpg, promocja.js, przeglądarka.txt, styl8.css. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem zdającego.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

    Podgląd strony bez zmian - taki jak po kroku 33.

Podgląd

To jedno z możliwych rozwiązań. Egzaminator ocenia spełnienie kryteriów z klucza odpowiedzi, a nie zgodność z tym kodem - inna, poprawna droga też daje punkty.

Autor rozwiązania: . Licencja CC BY-NC 4.0 - kopiowanie i przeróbki do celów niekomercyjnych, z podaniem autora i źródła (link do tej strony) (zasady wykorzystania). Treść arkusza i klucza oceniania pochodzi z CKE.