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

Rozwiązanie krok po kroku: Salon kosmetyczny z bazą (Wersja podstawowa)

Rozwiązanie buduje witrynę salonu kosmetycznego: baza salon i cztery zapytania - filtr cen, średnia i liczba w grupie (AVG, COUNT), nowy użytkownik bazy (CREATE USER) i nadanie mu uprawnień (GRANT), potem dwa obrazy przeskalowane do zadanej szerokości, dwie strony (index.html i twarz.html) z czterema blokami w dwóch kolumnach, style w styl7.css i skrypt JavaScript na stronie zabiegów na twarz: kalkulator, który sumuje ceny zaznaczonych zabiegów.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid, osobny skrypt)” jest drugi sposób rozwiązania tego samego arkusza: cztery bloki na siatce CSS z nazwanymi obszarami, kolory w zmiennych, pola wyboru w etykietach i skrypt w osobnym pliku z cennikiem w obiekcie - obie wersje są zgodne z kluczem.

Kroki idą zdanie po zdaniu za treścią arkusza - przy każdym jest polecenie z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Strona główna powstaje w całości, a twarz.html powstaje z jej kopii - różni się tylko drugim blokiem prawym. Skrypt jest najpierw pisany najprościej (onclick, osobny if dla każdego pola), a na końcu zostaje przerobiony na wersję z prawdziwych projektów.

Baza i grafiki pochodzą z prawdziwego archiwum materialy5 (załącznik do arkusza, hasło w treści zadania). Zapytania i zrzuty są policzone na MariaDB 10.4 - tej samej, która jest w XAMPP. Skrypt jest sprawdzony dla wszystkich 16 kombinacji zaznaczonych pól; w podglądzie strony twarz.html można zaznaczać zabiegi i klikać „Oblicz cenę”.

Jak liczą się punkty. Klucz ma 35 kryteriów (R.1.1 - R.5.6), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 27 punktów - można stracić 8 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.

  1. Etap 1: Baza danych

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

    Krok 1: Baza danych salon

    Kryteria:

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

    ok. 2 min
    Polecenie z arkusza

    Utwórz bazę danych o nazwie salon.

    Rozpakuj materialy5.7z z pulpitu (hasło Do!!@rozp@#) do folderu z numerem zdającego: egzamin.sql, obraz1.jpg i obraz2.jpg. W phpMyAdmin: Nowa, nazwa salon, porównywanie np. utf8_unicode_ci.

  2. Krok 2: Import tabel z pliku egzamin.sql

    Kryteria:

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

    ok. 2 min
    Polecenie z arkusza

    Do bazy salon zaimportuj tabele z pliku egzamin.sql z rozpakowanego archiwum.

    Import → egzamin.sql. Plik zawiera kilka tabel; w zadaniu potrzebne są dwie z obrazu 1: uslugi (10 usług z ceną i rodzajem: 1 - kosmetyczne, 2 - fryzjerskie, 3 - inne) i kadra (pracownicy).

  3. Krok 3: Zrzut ekranu import.png

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych salon 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.

    Print Screen i zapis jako import.png. Zrzuty zapytań mają być w JPEG (kw1.jpg - kw4.jpg) i zawierać treść zapytania.

    Typowe błędy

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

  4. Krok 4: Zapytanie 1: usługi od 50 zł

    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 nazwa i cena z tabeli uslugi dla usług, których cena jest wyższa lub równa 50 zł. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, cena FROM uslugi WHERE cena >= 50; oraz wynik działania udokumentowano zrzutem, na którym widoczne są jedynie dane: Farbowanie 50; Ustalenie diety 70; Paznokcie 90

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie pola nazwa i cena z tabeli uslugi dla usług, których cena jest wyższa lub równa 50 zł.

    • SELECT nazwa, cena FROM uslugi - dwie kolumny z tabeli usług,
    • WHERE cena >= 50 - „wyższa lub równa” to >=; usługa za dokładnie 50 zł też się liczy.

    Wynik: trzy usługi - Farbowanie 50, Ustalenie diety 70, Paznokcie 90, jak w kluczu. Zapytanie do kwerendy.txt, zrzut kw1.jpg.

    Typowe błędy

    cena > 50 gubi Farbowanie za równe 50 zł.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT nazwa, cena FROM uslugi WHERE cena >= 50;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: średnia cena i liczba usług kosmetycznych

    Kryteria:

    R.1.4 Wykonano zapytanie 2 liczące jedynie dla usług kosmetycznych średnią arytmetyczną cen usług oraz liczbę usług. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT AVG(cena), COUNT(*) FROM uslugi WHERE rodzaj = 1; oraz wynik działania udokumentowano zrzutem, na którym widoczne są liczby 36 i 5

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: liczące średnią arytmetyczną cen usług oraz liczbę usług jedynie dla usług kosmetycznych.

    • AVG(cena) - średnia arytmetyczna, COUNT(*) - liczba wierszy; obie funkcje zwracają jeden wiersz wyniku,
    • WHERE rodzaj = 1 - usługi kosmetyczne mają w polu rodzaj wartość 1 (opis tabeli w arkuszu).

    Wynik: 36 i 5 - pięć usług kosmetycznych o średniej cenie 36 zł, jak w kluczu. Zrzut kw2.jpg.

    Typowe błędy

    WHERE rodzaj = 'kosmetyczne' nic nie znajdzie - rodzaj jest liczbą, a nie nazwą.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, cena FROM uslugi WHERE cena >= 50;
    
    -- Zapytanie 2
    SELECT AVG(cena), COUNT(*) FROM uslugi WHERE rodzaj = 1;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: użytkownik kosmetyczka

    Kryteria:

    R.1.5 Wykonano zapytanie 3 tworzące użytkownika kosmetyczka na localhost z hasłem Kosmet34 W pliku z kwerendami lub na zrzucie istnieje zapis np.: CREATE USER 'kosmetyczka'@'localhost' IDENTIFIED BY 'Kosmet34'; oraz wynik działania udokumentowano zrzutem, na którym widoczny jest komunikat o pomyślnym wykonaniu zapytania oraz zapytanie z jawnie podanym hasłem

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: tworzące użytkownika kosmetyczka na localhost z hasłem Kosmet34.

    • CREATE USER 'kosmetyczka'@'localhost' - konto w MariaDB to para nazwa@host; localhost znaczy, że użytkownik może się logować tylko z tego samego komputera,
    • IDENTIFIED BY 'Kosmet34' - hasło jawnym tekstem, baza sama zapisze jego skrót.

    phpMyAdmin pokazuje komunikat o wykonaniu zapytania. Zrzut kw3.jpg - klucz wymaga, żeby było na nim widać zapytanie z hasłem.

    Typowe błędy

    Utworzenie konta przez kreator Konta użytkowników zamiast zapytania nie zostawia zapytania na zrzucie ani w kwerendach.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, cena FROM uslugi WHERE cena >= 50;
    
    -- Zapytanie 2
    SELECT AVG(cena), COUNT(*) FROM uslugi WHERE rodzaj = 1;
    
    -- Zapytanie 3
    CREATE USER 'kosmetyczka'@'localhost' IDENTIFIED BY 'Kosmet34';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: prawa do tabeli uslugi

    Kryteria:

    R.1.6 Wykonano zapytanie 4 nadające prawa przeglądania danych i aktualizacji do tabeli uslugi bazy salon dla użytkownika kosmetyczka. W pliku z kwerendami lub na zrzucie istnieje zapis np.: GRANT SELECT, UPDATE ON uslugi TO 'kosmetyczka'@'localhost'; oraz wynik działania udokumentowano zrzutem, na którym widoczny jest komunikat o poprawnym wykonaniu zapytania

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: nadające prawa przeglądania danych i aktualizacji do tabeli uslugi bazy salon dla użytkownika kosmetyczka.

    • GRANT SELECT, UPDATE - „przeglądanie danych” to SELECT, „aktualizacja” to UPDATE,
    • ON salon.uslugi - tylko jedna tabela jednej bazy (baza.tabela); salon.* dałoby prawa do wszystkich tabel bazy,
    • TO 'kosmetyczka'@'localhost' - dokładnie to konto, które utworzyło zapytanie 3.

    Sprawdzone: SHOW GRANTS dla tego konta zwraca GRANT SELECT, UPDATE ON salon.uslugi. Zrzut kw4.jpg.

    Typowe błędy

    TO kosmetyczka bez hosta odwołuje się w MariaDB do konta kosmetyczka@'%' - innego niż utworzone, więc zapytanie kończy się błędem.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, cena FROM uslugi WHERE cena >= 50;
    
    -- Zapytanie 2
    SELECT AVG(cena), COUNT(*) FROM uslugi WHERE rodzaj = 1;
    
    -- Zapytanie 3
    CREATE USER 'kosmetyczka'@'localhost' IDENTIFIED BY 'Kosmet34';
    
    -- Zapytanie 4
    GRANT SELECT, UPDATE ON salon.uslugi TO 'kosmetyczka'@'localhost';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strony HTML

    Kroki 8-26 · po tym etapie masz 18 z 35 kryteriów (pkt)

    Krok 8: Obrazy: szerokość 240 i 700 px

    Kryteria:

    R.2.1 Przynajmniej jedną grafikę przeskalowano z zachowaniem proporcji. Wymiary dla obraz1.jpg szerokość 240 px i odpowiadająca temu wysokość 300 px (± 5 px) lub obraz2.jpg szerokość 700 px i odpowiadająca temu wysokość 296 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 240 px. Plik obraz2.jpg, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji tak, aby jego szerokość wynosiła dokładnie 700 px.

    W GIMP-ie dla każdego pliku Obraz → Skaluj obraz z zamkniętym łańcuchem: obraz1.jpg - szerokość 240, wysokość wychodzi 300 px; obraz2.jpg - szerokość 700, wysokość 296 px - jak w kluczu. Plik → Nadpisz zostawia format JPG.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Krok 9: Plik index.html w HTML5

    Kryteria:

    R.2.2 Witrynę internetową zapisano w plikach index.html i twarz.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. 1 min
    Polecenie z arkusza

    Cechy witryny: Składa się ze stron o nazwach index.html oraz twarz.html. Obie strony różnią się jedynie drugim blokiem prawym. Strony index.html i twarz.html zapisane w języku HTML 5.

    Zbuduj w całości index.html, a twarz.html powstanie z jej kopii z innym drugim blokiem prawym.

    index.html HTML nowy plik
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  10. Krok 10: Język strony

    Kryteria:

    R.2.2 Witrynę internetową zapisano w plikach index.html i twarz.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. 1 min
    Polecenie z arkusza

    Ustawiony język zawartości stron na polski.

    Atrybut lang="pl" w znaczniku <html>.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  11. Krok 11: Kodowanie polskich znaków

    Kryteria:

    R.2.2 Witrynę internetową zapisano w plikach index.html i twarz.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. 1 min
    Polecenie z arkusza

    Jawnie zastosowany właściwy standard kodowania polskich znaków.

    <meta charset="UTF-8">.

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

    Kryteria:

    R.2.3 Stronie nadano tytuł: "Salon kosmetyczny"

    ok. 1 min
    Polecenie z arkusza

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

    <title> w <head>.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  13. Krok 13: Podpięcie arkusza stylów

    Kryteria:

    R.3.5 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl7.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 styl7.css prawidłowo połączony z kodem strony.

    Uwaga na nazwę z cyfrą: styl7.css.

    Typowe błędy

    styl.css bez siódemki odcina wszystkie style (R.3.5).

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  14. Krok 14: Bloki strony

    Kryteria:

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

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: dwa 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 układ bloków był zgodny z Obrazem 2.

    Cztery <section> w kolejności kolumnami: najpierw oba lewe, potem oba prawe. Obejmuje je kontener <div id="container">, a stopka stoi pod nim.

    Dlaczego tak, a nie float? Bloki lewe mają 400 i 330 px wysokości, a prawe 150 i 580 px - każdy wiersz byłby inny, więc pływające bloki rozjechałyby się. Kontener ułoży je w dwie kolumny w kroku układu CSS.

    index.html HTML zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
            </section>
            <section id="left2">
            </section>
            <section id="right1">
            </section>
            <section id="right2">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  15. Krok 15: Pierwszy blok lewy: nagłówek

    Kryteria:

    R.2.5 W bloku pierwszym lewym zapisano nagłówek h2: "Nasza oferta", w pierwszym prawym h1: "Usługi kosmetyczne" oraz w drugim prawym h3: "Telefon: 111 222 333" lub "Kalkulator ceny wizyty" oraz przynajmniej jeden paragraf

    ok. 1 min
    Polecenie z arkusza

    Zawartość pierwszego bloku po lewej stronie: Nagłówek drugiego stopnia o treści „Nasza oferta”.

    <h2>.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
            </section>
            <section id="left2">
            </section>
            <section id="right1">
            </section>
            <section id="right2">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  16. Krok 16: Lista numerowana

    Kryteria:

    R.2.6 Umieszczono jedną trójelementową listę numerowaną, której pierwszy element zagnieżdża dwuelementową listę punktowaną, zastosowano znaczniki <ol>, <ul>, <li>. Podlista <ul> zawarta wewnątrz pierwszego <li> listy głównej

    ok. 1 min
    Polecenie z arkusza

    Lista numerowana (uporządkowana) z elementami: Oczyszczanie twarzy, Masaż, Makijaż.

    Lista uporządkowana to <ol> - numery wstawia przeglądarka.

    index.html HTML zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li>Oczyszczanie twarzy</li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
            </section>
            <section id="left2">
            </section>
            <section id="right1">
            </section>
            <section id="right2">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  17. Krok 17: Lista zagnieżdżona

    Kryteria:

    R.2.6 Umieszczono jedną trójelementową listę numerowaną, której pierwszy element zagnieżdża dwuelementową listę punktowaną, zastosowano znaczniki <ol>, <ul>, <li>. Podlista <ul> zawarta wewnątrz pierwszego <li> listy głównej

    ok. 2 min
    Polecenie z arkusza

    Element „Oczyszczanie twarzy” zawiera zagnieżdżoną listę punktowaną (nieuporządkowaną) z elementami: Peeling, Maska.

    Zagnieżdżona lista stoi wewnątrz <li> - między tekstem „Oczyszczanie twarzy” a zamykającym </li>. Klucz sprawdza to wprost: podlista <ul> zawarta w pierwszym <li> listy głównej (R.2.6).

    Typowe błędy

    <ul> wstawione między dwa <li> (po zamknięciu pierwszego) to niepoprawny HTML i nie spełnia R.2.6.

    index.html HTML zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li>Oczyszczanie twarzy
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
            </section>
            <section id="left2">
            </section>
            <section id="right1">
            </section>
            <section id="right2">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  18. Krok 18: Odnośnik do twarz.html

    Kryteria:

    R.3.2 Po wybraniu odnośnika "Oczyszczanie twarzy" otwiera się strona twarz.html

    ok. 1 min
    Polecenie z arkusza

    Tekst elementu „Oczyszczanie twarzy” jest odnośnikiem do strony twarz.html.

    Sam tekst obejmujesz <a>; podlista zostaje poza odnośnikiem.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
            </section>
            <section id="left2">
            </section>
            <section id="right1">
            </section>
            <section id="right2">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  19. Krok 19: Odnośnik do strony głównej

    Kryteria:

    R.3.3 Po wybraniu odnośnika "Strona główna" otwiera się strona index.html

    ok. 1 min
    Polecenie z arkusza

    Odnośnik o treści „Strona główna” prowadzący do strony index.html.

    Odnośnik dostaje identyfikator home - arkusz każe nadać mu osobny styl (margines wewnętrzny 25 px).

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
            </section>
            <section id="right1">
            </section>
            <section id="right2">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  20. Krok 20: Pierwszy blok prawy: nagłówek

    Kryteria:

    R.2.5 W bloku pierwszym lewym zapisano nagłówek h2: "Nasza oferta", w pierwszym prawym h1: "Usługi kosmetyczne" oraz w drugim prawym h3: "Telefon: 111 222 333" lub "Kalkulator ceny wizyty" oraz przynajmniej jeden paragraf

    ok. 1 min
    Polecenie z arkusza

    Zawartość pierwszego bloku po prawej stronie: nagłówek pierwszego stopnia o treści „Usługi kosmetyczne”.

    <h1>.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
            </section>
            <section id="right1">
                <h1>Usługi kosmetyczne</h1>
            </section>
            <section id="right2">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  21. Krok 21: Drugi blok lewy: zdjęcie personelu

    Kryteria:

    R.2.7 Umieszczono co najmniej jedną grafikę: obraz1.jpg z tekstem alternatywnym "Personel" w bloku drugim lewym lub obraz2.jpg z tekstem alternatywnym "Zrelaksuj się" w bloku drugim prawym

    ok. 1 min
    Polecenie z arkusza

    Zawartość drugiego bloku po lewej stronie: obraz o nazwie obraz1.jpg z tekstem alternatywnym „Personel”.

    Obraz z atrybutem alt.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
                <img src="obraz1.jpg" alt="Personel">
            </section>
            <section id="right1">
                <h1>Usługi kosmetyczne</h1>
            </section>
            <section id="right2">
            </section>
        </div>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  22. Krok 22: Stopka

    Kryteria:

    R.2.5 W bloku pierwszym lewym zapisano nagłówek h2: "Nasza oferta", w pierwszym prawym h1: "Usługi kosmetyczne" oraz w drugim prawym h3: "Telefon: 111 222 333" lub "Kalkulator ceny wizyty" 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 - autor rozwiązania.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
                <img src="obraz1.jpg" alt="Personel">
            </section>
            <section id="right1">
                <h1>Usługi kosmetyczne</h1>
            </section>
            <section id="right2">
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  23. Krok 23: Drugi blok prawy strony głównej

    Kryteria: ,

    R.2.5 W bloku pierwszym lewym zapisano nagłówek h2: "Nasza oferta", w pierwszym prawym h1: "Usługi kosmetyczne" oraz w drugim prawym h3: "Telefon: 111 222 333" lub "Kalkulator ceny wizyty" oraz przynajmniej jeden paragraf

    R.2.7 Umieszczono co najmniej jedną grafikę: obraz1.jpg z tekstem alternatywnym "Personel" w bloku drugim lewym lub obraz2.jpg z tekstem alternatywnym "Zrelaksuj się" w bloku drugim prawym

    ok. 2 min
    Polecenie z arkusza

    Zawartość drugiego bloku po prawej stronie dla strony index.html: Akapit (paragraf) o treści: „Witaj! Miło nam, że odwiedziłeś nasz salon. Zapoznaj się z ofertą lub skontaktuj się z nami.” Obraz o nazwie obraz2.jpg z tekstem alternatywnym „Zrelaksuj się”. Nagłówek trzeciego stopnia o treści „Telefon: 111 222 333”.

    Akapit, obraz i <h3> - w tej kolejności, jak na obrazie 2.

    index.html HTML zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
                <img src="obraz1.jpg" alt="Personel">
            </section>
            <section id="right1">
                <h1>Usługi kosmetyczne</h1>
            </section>
            <section id="right2">
                <p>Witaj! Miło nam, że odwiedziłeś nasz salon. Zapoznaj się z ofertą lub skontaktuj się z nami.</p>
                <img src="obraz2.jpg" alt="Zrelaksuj się">
                <h3>Telefon: 111 222 333</h3>
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  24. Krok 24: Strona twarz.html z kopii

    Kryteria:

    R.2.5 W bloku pierwszym lewym zapisano nagłówek h2: "Nasza oferta", w pierwszym prawym h1: "Usługi kosmetyczne" oraz w drugim prawym h3: "Telefon: 111 222 333" lub "Kalkulator ceny wizyty" oraz przynajmniej jeden paragraf

    ok. 2 min
    Polecenie z arkusza

    Wygląd drugiego bloku po prawej stronie dla twarz.html przedstawiono na Obrazie 3, jego zawartość to: Nagłówek trzeciego stopnia o treści „Kalkulator ceny wizyty”.

    Zapisz jako twarz.html z kopii strony głównej - wymieniasz tylko zawartość #right2. Reszta (lista, odnośniki, zdjęcie, stopka) zostaje identyczna, jak każe arkusz.

    twarz.html HTML nowy plik
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
                <img src="obraz1.jpg" alt="Personel">
            </section>
            <section id="right1">
                <h1>Usługi kosmetyczne</h1>
            </section>
            <section id="right2">
                <h3>Kalkulator ceny wizyty</h3>
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (twarz.html)
  25. Krok 25: Cztery pola wyboru

    Kryteria:

    R.2.8 Na stronie twarz.html umieszczono cztery kontrolki checkbox z opisami: Peeling, Maska, Masaż twarzy, Makijaż oraz jeden przycisk "Oblicz cenę"

    ok. 2 min
    Polecenie z arkusza

    Cztery pola checkbox jeden pod drugim z podpisami: Peeling, Maska, Masaż twarzy, Makijaż.

    Każde pole z etykietą <label for> (kliknięcie podpisu zaznacza pole) i <br> po nim - dzięki temu pola stoją jedno pod drugim. Identyfikatory przydadzą się skryptowi.

    twarz.html HTML zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
                <img src="obraz1.jpg" alt="Personel">
            </section>
            <section id="right1">
                <h1>Usługi kosmetyczne</h1>
            </section>
            <section id="right2">
                <h3>Kalkulator ceny wizyty</h3>
                <input type="checkbox" id="peeling"><label for="peeling">Peeling</label><br>
                <input type="checkbox" id="mask"><label for="mask">Maska</label><br>
                <input type="checkbox" id="massage"><label for="massage">Masaż twarzy</label><br>
                <input type="checkbox" id="makeup"><label for="makeup">Makijaż</label><br>
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (twarz.html)
  26. Krok 26: Przycisk i akapit na wynik

    Kryteria: ,

    R.2.8 Na stronie twarz.html umieszczono cztery kontrolki checkbox z opisami: Peeling, Maska, Masaż twarzy, Makijaż oraz jeden przycisk "Oblicz cenę"

    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 = …)

    ok. 1 min
    Polecenie z arkusza

    Poniżej przycisk o treści „Oblicz cenę”, którego wybranie powoduje uruchomienie skryptu.

    onclick="calculate()" wywoła funkcję skryptu, a pusty <p id="result"> pod przyciskiem przyjmie wynik. Przycisk nie stoi w formularzu, więc niczego nie wysyła.

    twarz.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
                <img src="obraz1.jpg" alt="Personel">
            </section>
            <section id="right1">
                <h1>Usługi kosmetyczne</h1>
            </section>
            <section id="right2">
                <h3>Kalkulator ceny wizyty</h3>
                <input type="checkbox" id="peeling"><label for="peeling">Peeling</label><br>
                <input type="checkbox" id="mask"><label for="mask">Maska</label><br>
                <input type="checkbox" id="massage"><label for="massage">Masaż twarzy</label><br>
                <input type="checkbox" id="makeup"><label for="makeup">Makijaż</label><br>
                <button onclick="calculate()">Oblicz cenę</button>
                <p id="result"></p>
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (twarz.html)
  27. Etap 3: Styl CSS

    Kroki 27-34 · po tym etapie masz 29 z 35 kryteriów (pkt)

    Krok 27: Plik styl7.css: czcionka dla wszystkich

    Kryteria:

    R.4.1 Ustawiono domyślne formatowanie wszystkich selektorów (*): krój czcionki Cambria

    ok. 1 min
    Polecenie z arkusza

    Ustawione domyślne wartości dla wszystkich selektorów stylu CSS: krój czcionki Cambria.

    Selektor uniwersalny *.

    styl7.css CSS nowy plik
    * {
        font-family: Cambria;
    }
    Podgląd strony po tym kroku (index.html)
  28. Krok 28: Bloki lewe

    Kryteria: , ,

    R.4.2 Ustawiono kolor tła #E1BEE7 dla obu bloków lewych oraz #9C64A6 dla pierwszego bloku prawego i stopki

    R.4.4 Ustawiono szerokość 25% dla obu bloków lewych i 75% dla obu prawych (width lub grid- template-columns lub flex)

    R.4.5 Ustawiono wysokość dla bloków: pierwszy lewy: 400px, drugi lewy: 330px, pierwszy prawy: 150px, drugi prawy: 580px

    ok. 2 min
    Polecenie z arkusza

    Wspólne dla obu bloków lewych: kolor tła #E1BEE7, szerokość 25%. Dodatkowo wysokość pierwszego lewego bloku wynosi 400 px, drugiego 330 px.

    Wspólne cechy w jednej regule, wysokości osobno.

    styl7.css CSS zmienione: 10 linii
    * {
        font-family: Cambria;
    }
    #left1, #left2 {
        background-color: #E1BEE7;
        width: 25%;
    }
    #left1 {
        height: 400px;
    }
    #left2 {
        height: 330px;
    }
    Podgląd strony po tym kroku (index.html)
  29. Krok 29: Bloki prawe

    Kryteria: , , , , ,

    R.4.2 Ustawiono kolor tła #E1BEE7 dla obu bloków lewych oraz #9C64A6 dla pierwszego bloku prawego i stopki

    R.4.3 Ustawiono biały kolor czcionki dla pierwszego bloku prawego i stopki oraz Indigo dla drugiego bloku prawego

    R.4.4 Ustawiono szerokość 25% dla obu bloków lewych i 75% dla obu prawych (width lub grid- template-columns lub flex)

    R.4.5 Ustawiono wysokość dla bloków: pierwszy lewy: 400px, drugi lewy: 330px, pierwszy prawy: 150px, drugi prawy: 580px

    R.4.7 Ustawiono wyrównanie do środka dla obu bloków prawych i selektora h2

    R.4.8 Ustawiono dla obu bloków prawych rozmiar czcionki 170% oraz dla pierwszego prawego odstępy między literami 5px (letter-spacing)

    ok. 3 min
    Polecenie z arkusza

    Wspólne dla obu bloków prawych: szerokość 75%, rozmiar czcionki 170%, wyrównanie tekstu do środka. Dodatkowo dla pierwszego bloku prawego: kolor tła #9C64A6, biały kolor czcionki, wysokość 150 px, odstępy między literami 5 px. Dodatkowo dla drugiego bloku prawego: kolor czcionki Indigo, wysokość 580 px.

    Odstępy między literami to letter-spacing (między wyrazami byłoby word-spacing) - stąd rozstrzelony napis „Usługi kosmetyczne”.

    styl7.css CSS zmienione: 15 linii
    * {
        font-family: Cambria;
    }
    #left1, #left2 {
        background-color: #E1BEE7;
        width: 25%;
    }
    #left1 {
        height: 400px;
    }
    #left2 {
        height: 330px;
    }
    #right1, #right2 {
        width: 75%;
        font-size: 170%;
        text-align: center;
    }
    #right1 {
        background-color: #9C64A6;
        color: white;
        height: 150px;
        letter-spacing: 5px;
    }
    #right2 {
        color: Indigo;
        height: 580px;
    }
    Podgląd strony po tym kroku (index.html)
  30. Krok 30: Stopka

    Kryteria: , ,

    R.4.2 Ustawiono kolor tła #E1BEE7 dla obu bloków lewych oraz #9C64A6 dla pierwszego bloku prawego i stopki

    R.4.3 Ustawiono biały kolor czcionki dla pierwszego bloku prawego i stopki oraz Indigo dla drugiego bloku prawego

    R.4.6 Ustawiono marginesy wewnętrzne (padding) 10px dla stopki, 4px dla selektora img i 25px dla odsyłacza do Strony głównej oraz marginesy zewnętrzne (margin) 15px dla selektora img

    ok. 1 min
    Polecenie z arkusza

    Dla stopki: kolor tła #9C64A6, biały kolor czcionki, marginesy wewnętrzne 10 px.

    Selektor footer.

    styl7.css CSS zmienione: 5 linii
    * {
        font-family: Cambria;
    }
    #left1, #left2 {
        background-color: #E1BEE7;
        width: 25%;
    }
    #left1 {
        height: 400px;
    }
    #left2 {
        height: 330px;
    }
    #right1, #right2 {
        width: 75%;
        font-size: 170%;
        text-align: center;
    }
    #right1 {
        background-color: #9C64A6;
        color: white;
        height: 150px;
        letter-spacing: 5px;
    }
    #right2 {
        color: Indigo;
        height: 580px;
    }
    footer {
        background-color: #9C64A6;
        color: white;
        padding: 10px;
    }
    Podgląd strony po tym kroku (index.html)
  31. Krok 31: Nagłówek drugiego stopnia i lista punktowana

    Kryteria: ,

    R.4.7 Ustawiono wyrównanie do środka dla obu bloków prawych i selektora h2

    R.4.9 Ustawiono dla selektora ul: okrąg jako punktor (list-style lub list-style-type: circle;)

    ok. 1 min
    Polecenie z arkusza

    Dla selektora nagłówka drugiego stopnia: wyrównanie tekstu do środka. Dla selektora listy punktowanej (nieuporządkowanej): punktorem jest okrąg.

    Selektory znaczników h2 i ul, jak wymaga arkusz. Okrąg to circle.

    styl7.css CSS zmienione: 6 linii
    * {
        font-family: Cambria;
    }
    #left1, #left2 {
        background-color: #E1BEE7;
        width: 25%;
    }
    #left1 {
        height: 400px;
    }
    #left2 {
        height: 330px;
    }
    #right1, #right2 {
        width: 75%;
        font-size: 170%;
        text-align: center;
    }
    #right1 {
        background-color: #9C64A6;
        color: white;
        height: 150px;
        letter-spacing: 5px;
    }
    #right2 {
        color: Indigo;
        height: 580px;
    }
    footer {
        background-color: #9C64A6;
        color: white;
        padding: 10px;
    }
    h2 {
        text-align: center;
    }
    ul {
        list-style-type: circle;
    }
    Podgląd strony po tym kroku (index.html)
  32. Krok 32: Obrazy i ramka po wskazaniu

    Kryteria: ,

    R.4.6 Ustawiono marginesy wewnętrzne (padding) 10px dla stopki, 4px dla selektora img i 25px dla odsyłacza do Strony głównej oraz marginesy zewnętrzne (margin) 15px dla selektora img

    R.4.10 W momencie, gdy kursor znajduje się na obrazie, styl obrazu zmienia się na: marginesy wewnętrzne (padding) 3px oraz obramowanie 1px dashed Indigo

    ok. 2 min
    Polecenie z arkusza

    Dla selektora obrazu: marginesy wewnętrzne 4 px, marginesy zewnętrzne 15 px. W momencie, gdy kursor znajduje się na obrazie, styl obrazu zmienia się na: marginesy wewnętrzne 3 px, obramowanie linią kreskową o szerokości 1 px i kolorze Indigo.

    Linia kreskowa to dashed. Zauważ sztuczkę z arkusza: po wskazaniu margines wewnętrzny maleje o 1 px dokładnie wtedy, gdy pojawia się ramka 1 px - obraz zajmuje tyle samo miejsca i nic na stronie nie podskakuje. Najedź w podglądzie na obraz.

    styl7.css CSS zmienione: 8 linii
    * {
        font-family: Cambria;
    }
    #left1, #left2 {
        background-color: #E1BEE7;
        width: 25%;
    }
    #left1 {
        height: 400px;
    }
    #left2 {
        height: 330px;
    }
    #right1, #right2 {
        width: 75%;
        font-size: 170%;
        text-align: center;
    }
    #right1 {
        background-color: #9C64A6;
        color: white;
        height: 150px;
        letter-spacing: 5px;
    }
    #right2 {
        color: Indigo;
        height: 580px;
    }
    footer {
        background-color: #9C64A6;
        color: white;
        padding: 10px;
    }
    h2 {
        text-align: center;
    }
    ul {
        list-style-type: circle;
    }
    img {
        padding: 4px;
        margin: 15px;
    }
    img:hover {
        padding: 3px;
        border: 1px dashed Indigo;
    }
    Podgląd strony po tym kroku (index.html)
  33. Krok 33: Odnośnik do strony głównej

    Kryteria:

    R.4.6 Ustawiono marginesy wewnętrzne (padding) 10px dla stopki, 4px dla selektora img i 25px dla odsyłacza do Strony głównej oraz marginesy zewnętrzne (margin) 15px dla selektora img

    ok. 1 min
    Polecenie z arkusza

    Dla odsyłacza do Strony głównej: margines wewnętrzny 25 px.

    Selektor identyfikatora #home - tylko ten jeden odnośnik.

    styl7.css CSS zmienione: 3 linie
    * {
        font-family: Cambria;
    }
    #left1, #left2 {
        background-color: #E1BEE7;
        width: 25%;
    }
    #left1 {
        height: 400px;
    }
    #left2 {
        height: 330px;
    }
    #right1, #right2 {
        width: 75%;
        font-size: 170%;
        text-align: center;
    }
    #right1 {
        background-color: #9C64A6;
        color: white;
        height: 150px;
        letter-spacing: 5px;
    }
    #right2 {
        color: Indigo;
        height: 580px;
    }
    footer {
        background-color: #9C64A6;
        color: white;
        padding: 10px;
    }
    h2 {
        text-align: center;
    }
    ul {
        list-style-type: circle;
    }
    img {
        padding: 4px;
        margin: 15px;
    }
    img:hover {
        padding: 3px;
        border: 1px dashed Indigo;
    }
    #home {
        padding: 25px;
    }
    Podgląd strony po tym kroku (index.html)
  34. Krok 34: Układ: dwie kolumny bloków

    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. 3 min
    Polecenie z arkusza

    Podział strony na bloki: dwa 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 układ bloków był zgodny z Obrazem 2.

    Kontener ustawiasz jako flex w kolumnie z zawijaniem: bloki układają się z góry na dół, a gdy kolumna się zapełni, następne przechodzą do nowej kolumny obok.

    • flex-direction: column - bloki jeden pod drugim,
    • flex-wrap: wrap - po zapełnieniu kolumny przejście do następnej,
    • height: 730px - wysokość kolumny: 400 + 330 px bloków lewych (i tyle samo 150 + 580 px prawych), więc oba lewe mieszczą się w pierwszej kolumnie, a prawe przechodzą do drugiej.

    Szerokości 25% i 75% bloków dają razem cały wiersz.

    Typowe błędy

    float: left dla wszystkich czterech bloków nie zadziała przy różnych wysokościach: drugi blok lewy wskoczy obok pierwszego, pod pierwszy prawy.

    styl7.css CSS zmienione: 6 linii
    * {
        font-family: Cambria;
    }
    #left1, #left2 {
        background-color: #E1BEE7;
        width: 25%;
    }
    #left1 {
        height: 400px;
    }
    #left2 {
        height: 330px;
    }
    #right1, #right2 {
        width: 75%;
        font-size: 170%;
        text-align: center;
    }
    #right1 {
        background-color: #9C64A6;
        color: white;
        height: 150px;
        letter-spacing: 5px;
    }
    #right2 {
        color: Indigo;
        height: 580px;
    }
    footer {
        background-color: #9C64A6;
        color: white;
        padding: 10px;
    }
    h2 {
        text-align: center;
    }
    ul {
        list-style-type: circle;
    }
    img {
        padding: 4px;
        margin: 15px;
    }
    img:hover {
        padding: 3px;
        border: 1px dashed Indigo;
    }
    #home {
        padding: 25px;
    }
    #container {
        display: flex;
        flex-direction: column;
        flex-wrap: wrap;
        height: 730px;
    }
    Podgląd strony po tym kroku (index.html)
  35. Etap 4: Skrypt JavaScript

    Kroki 35-38 · po tym etapie masz 35 z 35 kryteriów (pkt)

    Krok 35: Funkcja calculate

    Kryteria:

    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. 2 min
    Polecenie z arkusza

    Skrypt napisany w języku wykonywanym po stronie przeglądarki. Uruchamia się po wciśnięciu przycisku na stronie twarz.html.

    Skrypt w <script> na końcu <body> strony twarz.html, funkcja o nazwie z onclick: calculate (oblicz).

    twarz.html HTML zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
                <img src="obraz1.jpg" alt="Personel">
            </section>
            <section id="right1">
                <h1>Usługi kosmetyczne</h1>
            </section>
            <section id="right2">
                <h3>Kalkulator ceny wizyty</h3>
                <input type="checkbox" id="peeling"><label for="peeling">Peeling</label><br>
                <input type="checkbox" id="mask"><label for="mask">Maska</label><br>
                <input type="checkbox" id="massage"><label for="massage">Masaż twarzy</label><br>
                <input type="checkbox" id="makeup"><label for="makeup">Makijaż</label><br>
                <button onclick="calculate()">Oblicz cenę</button>
                <p id="result"></p>
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
        <script>
            function calculate() {
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (twarz.html)
  36. Krok 36: Cena peelingu

    Kryteria: ,

    R.5.2 Skrypt wykorzystuje przynajmniej jedną metodę DOM

    R.5.3 Skrypt stosuje własność checked dla przynajmniej jednego pola checkbox

    ok. 2 min
    Polecenie z arkusza

    Oblicza łączną cenę zabiegów wybranych za pomocą pól checkbox zgodnie z cennikiem w tabeli.

    Zmienna sum zaczyna od zera. document.getElementById("peeling") znajduje pole, a jego właściwość checked jest true, gdy pole jest zaznaczone - wtedy doliczasz 45 zł z cennika.

    twarz.html HTML zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
                <img src="obraz1.jpg" alt="Personel">
            </section>
            <section id="right1">
                <h1>Usługi kosmetyczne</h1>
            </section>
            <section id="right2">
                <h3>Kalkulator ceny wizyty</h3>
                <input type="checkbox" id="peeling"><label for="peeling">Peeling</label><br>
                <input type="checkbox" id="mask"><label for="mask">Maska</label><br>
                <input type="checkbox" id="massage"><label for="massage">Masaż twarzy</label><br>
                <input type="checkbox" id="makeup"><label for="makeup">Makijaż</label><br>
                <button onclick="calculate()">Oblicz cenę</button>
                <p id="result"></p>
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
        <script>
            function calculate() {
                let sum = 0;
                if (document.getElementById("peeling").checked) {
                    sum = sum + 45;
                }
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (twarz.html)
  37. Krok 37: Pozostałe zabiegi

    Kryteria:

    R.5.4 Skrypt liczy sumę jedynie wszystkich zaznaczonych pól checkbox zgodnie z cenami podanymi w tabeli w arkuszu

    ok. 2 min
    Polecenie z arkusza

    Cennik: Peeling 45, Maska 30, Masaż 20, Makijaż 50.

    Cztery osobne if, nie else if - zaznaczyć można dowolną liczbę zabiegów i każdy ma się doliczyć. Masaż twarzy kosztuje 20 zł (w cenniku „Masaż”).

    Typowe błędy

    else if liczy tylko pierwszy zaznaczony zabieg.

    twarz.html HTML zmienione: 9 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
                <img src="obraz1.jpg" alt="Personel">
            </section>
            <section id="right1">
                <h1>Usługi kosmetyczne</h1>
            </section>
            <section id="right2">
                <h3>Kalkulator ceny wizyty</h3>
                <input type="checkbox" id="peeling"><label for="peeling">Peeling</label><br>
                <input type="checkbox" id="mask"><label for="mask">Maska</label><br>
                <input type="checkbox" id="massage"><label for="massage">Masaż twarzy</label><br>
                <input type="checkbox" id="makeup"><label for="makeup">Makijaż</label><br>
                <button onclick="calculate()">Oblicz cenę</button>
                <p id="result"></p>
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
        <script>
            function calculate() {
                let sum = 0;
                if (document.getElementById("peeling").checked) {
                    sum = sum + 45;
                }
                if (document.getElementById("mask").checked) {
                    sum = sum + 30;
                }
                if (document.getElementById("massage").checked) {
                    sum = sum + 20;
                }
                if (document.getElementById("makeup").checked) {
                    sum = sum + 50;
                }
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (twarz.html)
  38. Krok 38: Wynik pod przyciskiem

    Kryteria: ,

    R.5.5 Skrypt wyświetla obliczony wynik w akapicie pod przyciskiem według wzoru: "Cena zabiegów: <suma>”, gdzie <suma> oznacza sumę wyliczoną przez skrypt

    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

    Wyświetla wynik działania w akapicie pod przyciskiem według wzoru: „Cena zabiegów: <suma>”, gdzie <suma> oznacza całkowitą cenę wybranych zabiegów.

    Wynik wpisujesz do akapitu result. Zaznacz w podglądzie Maskę, Masaż twarzy i Makijaż i kliknij „Oblicz cenę” - wyjdzie 100, jak na obrazie 3. Nazwy zmiennych i funkcji są po angielsku i mówią, co przechowują (R.5.6).

    twarz.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
                <img src="obraz1.jpg" alt="Personel">
            </section>
            <section id="right1">
                <h1>Usługi kosmetyczne</h1>
            </section>
            <section id="right2">
                <h3>Kalkulator ceny wizyty</h3>
                <input type="checkbox" id="peeling"><label for="peeling">Peeling</label><br>
                <input type="checkbox" id="mask"><label for="mask">Maska</label><br>
                <input type="checkbox" id="massage"><label for="massage">Masaż twarzy</label><br>
                <input type="checkbox" id="makeup"><label for="makeup">Makijaż</label><br>
                <button onclick="calculate()">Oblicz cenę</button>
                <p id="result"></p>
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
        <script>
            function calculate() {
                let sum = 0;
                if (document.getElementById("peeling").checked) {
                    sum = sum + 45;
                }
                if (document.getElementById("mask").checked) {
                    sum = sum + 30;
                }
                if (document.getElementById("massage").checked) {
                    sum = sum + 20;
                }
                if (document.getElementById("makeup").checked) {
                    sum = sum + 50;
                }
                document.getElementById("result").innerHTML = "Cena zabiegów: " + sum;
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (twarz.html)
  39. Etap 5: Dobre praktyki (poza kluczem)

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

    Krok 39: Ceny w HTML, jedna pętla zamiast czterech if

    ok. 5 min
    Polecenie z arkusza

    Oblicza łączną cenę zabiegów wybranych za pomocą pól checkbox zgodnie z cennikiem w tabeli.

    Wersja z egzaminu ma ceny wpisane w skrypt i osobny if dla każdego pola - nowy zabieg w ofercie to zmiana w dwóch miejscach. Teraz:

    • każde pole niesie swoją cenę w atrybucie data-price i ma wspólną klasę treatment,
    • skrypt przechodzi pętlą po document.querySelectorAll(".treatment") i dolicza Number(checkbox.dataset.price) z zaznaczonych pól - piąty zabieg to jedna linia HTML, bez zmian w skrypcie,
    • addEventListener zamiast onclick, textContent zamiast innerHTML (wpisujesz zwykły tekst).

    Sprawdzone dla wszystkich 16 kombinacji pól - wyniki identyczne z wersją egzaminacyjną. Stary kod zostaje w komentarzu. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    twarz.html HTML zmienione: 29 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Salon kosmetyczny</title>
        <link rel="stylesheet" href="styl7.css">
    </head>
    <body>
        <div id="container">
            <section id="left1">
                <h2>Nasza oferta</h2>
                <ol>
                    <li><a href="twarz.html">Oczyszczanie twarzy</a>
                        <ul>
                            <li>Peeling</li>
                            <li>Maska</li>
                        </ul>
                    </li>
                    <li>Masaż</li>
                    <li>Makijaż</li>
                </ol>
                <a href="index.html" id="home">Strona główna</a>
            </section>
            <section id="left2">
                <img src="obraz1.jpg" alt="Personel">
            </section>
            <section id="right1">
                <h1>Usługi kosmetyczne</h1>
            </section>
            <section id="right2">
                <h3>Kalkulator ceny wizyty</h3>
                <input type="checkbox" id="peeling" class="treatment" data-price="45"><label for="peeling">Peeling</label><br>
                <input type="checkbox" id="mask" class="treatment" data-price="30"><label for="mask">Maska</label><br>
                <input type="checkbox" id="massage" class="treatment" data-price="20"><label for="massage">Masaż twarzy</label><br>
                <input type="checkbox" id="makeup" class="treatment" data-price="50"><label for="makeup">Makijaż</label><br>
                <button id="calculate">Oblicz cenę</button>
                <p id="result"></p>
            </section>
        </div>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
        <script>
            // wersja z egzaminu - cztery osobne if z cenami w skrypcie
            // function calculate() {
            //     let sum = 0;
            //     if (document.getElementById("peeling").checked) {
            //         sum = sum + 45;
            //     }
            //     if (document.getElementById("mask").checked) {
            //         sum = sum + 30;
            //     }
            //     if (document.getElementById("massage").checked) {
            //         sum = sum + 20;
            //     }
            //     if (document.getElementById("makeup").checked) {
            //         sum = sum + 50;
            //     }
            //     document.getElementById("result").innerHTML = "Cena zabiegów: " + sum;
            // }
            function calculate() {
                let sum = 0;
                for (const checkbox of document.querySelectorAll(".treatment")) {
                    if (checkbox.checked) {
                        sum += Number(checkbox.dataset.price);
                    }
                }
                document.getElementById("result").textContent = "Cena zabiegów: " + sum;
            }
    
            document.getElementById("calculate").addEventListener("click", calculate);
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (twarz.html)
  40. Etap 6: Oddanie pracy

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

    Krok 40: 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 wpisujesz nazwę przeglądarki.

    W folderze: import.png, index.html, kw1.jpg - kw4.jpg, kwerendy.txt, obraz1.jpg, obraz2.jpg, przeglądarka.txt, styl7.css, twarz.html. 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 39.

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.