Przejdź do głównej treści
INF.03-02-22.06-SGCzerwiec 2022 · 45 kroków · ok. 81 min · 38 kryteriów z klucza

Rozwiązanie krok po kroku: Portal stacji paliw (Nowoczesny kod (grid, JS w pliku))

To drugi sposób rozwiązania tego samego arkusza. Wynik jest ten sam - baza samochody z pięcioma zapytaniami, przygotowane grafiki i dwie strony, stacja.html z godzinami otwarcia i obliczenia.html z kalkulatorem kosztu paliwa - i tak samo spełnia każde kryterium klucza. Inna jest droga:

  • siatka CSS zamiast float: bloki lewy i prawy stoją w znaczniku <main> z kolumnami 60% i 40% - klucz wprost dopuszcza szerokości w grid-template-columns; stopka nie potrzebuje clear,
  • zmienne CSS dla kolorów z arkusza, bloki nazwane po treści (#info, #photo), wiersze formularza w blokach <div> zamiast <br>,
  • skrypt w osobnym pliku obliczenia.js podpięty z defer: formularz z obsługą zdarzenia submit (działa też klawisz Enter), cennik w obiekcie PRICES zamiast drabinki if, wynik w znaczniku <output> z kwotą zawsze z dwoma miejscami po przecinku,
  • komunikat przy złej liczbie litrów - pustej, zerowej albo ujemnej.

Zapytania SQL są takie same jak w wersji podstawowej - klucz wymaga przy zapytaniu 2 nawiasu z OR, więc nie ma tu czego zmieniać. Na końcu krótkie porównanie z wersją podstawową (zakładka obok). Skrypt jest przetestowany w przeglądarce Chrome, a podgląd strony obliczenia.html działa - można wpisać wartości i kliknąć OBLICZ.

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

  1. Etap 1: Baza danych

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

    Krok 1: Baza danych samochody

    ok. 2 min
    Polecenie z arkusza

    Utwórz bazę danych o nazwie samochody

    Rozpakuj pliki2.zip z pulpitu (hasło PaLiWo5& - wielkość liter ma znaczenie, na końcu znak &) do folderu z numerem zdającego: baza.sql, home.png, znak.png i samochod.jpg. W phpMyAdmin Nowa → samochody albo zapytaniem:

    CREATE DATABASE samochody CHARACTER SET utf8mb4 COLLATE utf8mb4_polish_ci;
    

    Arkusz nie podaje porównywania, więc wybór należy do Ciebie. Tabele z baza.sql mają zestaw znaków zapisany we własnej definicji, więc ustawienie bazy ich nie zmienia.

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

    ok. 2 min
    Polecenie z arkusza

    Do bazy samochody zaimportuj tabele z pliku baza.sql z rozpakowanego archiwum

    Przy zaznaczonej bazie samochody: Import → baza.sql → Wykonaj. Plik zawiera kilka tabel z różnych zadań; tu potrzebna jest jedna - samochody z obrazu 1: 8 aut z marką, modelem, rocznikiem (typ YEAR), kolorem i stanem.

  3. Krok 3: Zrzut ekranu import.png

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych samochody 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 i nazwij import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel

    Print Screen, cały ekran z paskiem zadań, zapis jako import.png. Uwaga na formaty: import idzie do PNG, a zrzuty zapytań do JPEG.

    Typowe błędy

    Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).

  4. Krok 4: Zapytanie 1: niebieskie samochody

    Kryteria: ,

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

    R.1.3 Utworzono zapytanie 1 wybierające jedynie pola marka i rocznik z tabeli samochody dla samochodów koloru niebieskiego. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT marka, rocznik FROM samochody WHERE kolor="niebieski"; oraz wynik działania udokumentowano zrzutem, na którym widoczne są dokładnie dwa rekordy: Fiat 2007, Opel 2003

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie pola marka i rocznik z tabeli samochody dla samochodów koloru niebieskiego

    Kolor w bazie jest zapisany małymi literami, w rodzaju męskim: niebieski. Wynik: dokładnie dwa wiersze - Fiat 2007 i Opel 2003, jak w kluczu. Zapytania trafiają do kwerendy.txt, zrzut wyniku do kw1.jpg.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT marka, rocznik FROM samochody WHERE kolor = 'niebieski';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: Toyoty i Ople w bardzo dobrym stanie

    Kryteria:

    R.1.4 Utworzono zapytanie 2 zliczające ile jest samochodów marki Toyota lub Opel, których stan jest bardzo dobry. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT COUNT(*) FROM samochody WHERE (marka = "Toyota" OR marka = "Opel") AND stan="bardzo dobry"; (nawias wymagany, w COUNT poprawna też nazwa dowolnego pola) oraz wynik działania udokumentowano zrzutem, na którym jest widoczna wartość 2

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 2: zliczające ile jest samochodów marki Toyota lub Opel, których stan jest bardzo dobry

    COUNT(*) liczy wiersze spełniające warunek. Nawias wokół OR jest konieczny: AND wiąże mocniej niż OR, więc bez nawiasu baza czyta warunek jako „każda Toyota albo Opel w bardzo dobrym stanie” i zwraca 4 zamiast 2 (sprawdzone na bazie z archiwum). Wynik: 2 (Opel Corsa i Toyota Corolla z 2016 roku). Zrzut: kw2.jpg.

    Ten sam warunek da się zapisać krócej - marka IN ('Toyota', 'Opel') - ale klucz przy R.1.4 pisze wprost „nawias wymagany”, więc na egzaminie bezpieczniej zostać przy zapisie z OR.

    Typowe błędy

    Zapytanie bez nawiasu daje 4 zamiast 2 i nie jest uznawane.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT marka, rocznik FROM samochody WHERE kolor = 'niebieski';
    
    -- Zapytanie 2
    SELECT COUNT(*) FROM samochody WHERE (marka = 'Toyota' OR marka = 'Opel') AND stan = 'bardzo dobry';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: stan „dobry” dla aut starszych niż 2004

    Kryteria:

    R.1.5 Utworzono zapytanie 3 aktualizujące wartość pola stan na „dobry” w tabeli samochody dla samochodów starszych niż 2004 rok. W pliku z kwerendami lub na zrzucie istnieje zapis np.: UPDATE samochody SET stan = "dobry" WHERE rocznik < 2004; oraz wynik działania udokumentowano zrzutem, na którym widoczny jest komunikat o wykonaniu kwerendy lub zmienione wartości w tabeli

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: aktualizujące wartość pola stan na „dobry” w tabeli samochody dla samochodów starszych niż 2004 rok

    „Starszy niż 2004” to rocznik mniejszy od 2004 - Toyota Yaris z 2004 roku się nie zmienia. Warunek spełniają dwa auta (Fiat z 2002 i Opel z 2003), ale phpMyAdmin pokazuje komunikat o jednym zmodyfikowanym rekordzie: Fiat miał już stan „dobry”, a baza liczy tylko wiersze, w których wartość naprawdę się zmieniła. Zrzut kw3.jpg.

    Typowe błędy

    UPDATE bez WHERE zmienia stan wszystkim autom - phpMyAdmin wykona to bez pytania.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT marka, rocznik FROM samochody WHERE kolor = 'niebieski';
    
    -- Zapytanie 2
    SELECT COUNT(*) FROM samochody WHERE (marka = 'Toyota' OR marka = 'Opel') AND stan = 'bardzo dobry';
    
    -- Zapytanie 3
    UPDATE samochody SET stan = 'dobry' WHERE rocznik < 2004;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: użytkownik jan

    Kryteria:

    R.1.6 Utworzono zapytanie 4 tworzące użytkownika jan na localhost z hasłem janKowalski1@. W pliku z kwerendami lub na zrzucie istnieje zapis np.: CREATE USER "jan"@"localhost" IDENTIFIED BY "janKowalski1@"; oraz wynik działania udokumentowano zrzutem, na którym jest widoczne wykonane zapytanie z nazwą konta i niezaszyfrowanym hasłem

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: tworzące użytkownika jan na localhost z hasłem janKowalski1@

    Konto to nazwa i host, z którego można się logować: 'jan'@'localhost'. Hasło po IDENTIFIED BY podajesz jawnie - baza zapisze jego skrót. Zapytanie wykonaj w zakładce SQL (nie formularzem Konta użytkowników), bo klucz wymaga zrzutu z treścią zapytania, nazwą konta i niezaszyfrowanym hasłem. Zrzut: kw4.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT marka, rocznik FROM samochody WHERE kolor = 'niebieski';
    
    -- Zapytanie 2
    SELECT COUNT(*) FROM samochody WHERE (marka = 'Toyota' OR marka = 'Opel') AND stan = 'bardzo dobry';
    
    -- Zapytanie 3
    UPDATE samochody SET stan = 'dobry' WHERE rocznik < 2004;
    
    -- Zapytanie 4
    CREATE USER 'jan'@'localhost' IDENTIFIED BY 'janKowalski1@';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Krok 8: Zapytanie 5: uprawnienia dla jan do tabeli samochody

    Kryteria:

    R.1.7 Utworzono zapytanie 5 nadające użytkownikowi jan prawo jedynie do wybierania, wstawiania i aktualizacji danych w tabeli samochody . W pliku z kwerendami lub na zrzucie istnieje zapis np.: GRANT SELECT, INSERT, UPDATE ON samochody TO "jan"@"localhost"; oraz wynik działania udokumentowano zrzutem, na którym jest widoczne wykonane zapytanie

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 5: nadające użytkownikowi jan prawo jedynie do wybierania, wstawiania i aktualizacji danych w tabeli samochody

    GRANT SELECT, INSERT, UPDATE - bez DELETE i bez zmian struktury; ON samochody.samochody - zapis baza.tabela, uprawnienie dotyczy tylko tej tabeli. Sprawdzone logowaniem jako jan: SELECT z tabeli samochody działa, a DELETE i SELECT z innej tabeli kończą się odmową dostępu. Zrzut kw5.jpg.

    Typowe błędy

    GRANT ALL albo ON *.* daje więcej, niż każe arkusz („jedynie”).

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT marka, rocznik FROM samochody WHERE kolor = 'niebieski';
    
    -- Zapytanie 2
    SELECT COUNT(*) FROM samochody WHERE (marka = 'Toyota' OR marka = 'Opel') AND stan = 'bardzo dobry';
    
    -- Zapytanie 3
    UPDATE samochody SET stan = 'dobry' WHERE rocznik < 2004;
    
    -- Zapytanie 4
    CREATE USER 'jan'@'localhost' IDENTIFIED BY 'janKowalski1@';
    
    -- Zapytanie 5
    GRANT SELECT, INSERT, UPDATE ON samochody.samochody TO 'jan'@'localhost';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Etap 2: Grafika i strony HTML

    Kroki 9-26 · po tym etapie masz 21 z 38 kryteriów (pkt)

    Krok 9: Ikony home.png i znak.png: szerokość 80 px

    Kryteria:

    R.2.1 Przynajmniej jedną grafikę z plików home.png lub znak.png przeskalowano z zachowaniem proporcji do szerokości 80 px, odpowiadająca temu wysokość wynosi 80 px (± 2 px)

    ok. 2 min
    Polecenie z arkusza

    Pliki home.png i znak.png należy przeskalować z zachowaniem proporcji do szerokości 80 px

    Grafiki są takie same jak w wersji podstawowej. W GIMP-ie Obraz → Skaluj obraz, łańcuch proporcji zamknięty, szerokość 80 px - wysokość też wyjdzie 80, bo obie ikony są kwadratami 200 × 200. Zapis pod tą samą nazwą w PNG - przezroczyste tło zostaje.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 9
  10. Krok 10: samochod.png z przezroczystym tłem

    Kryteria:

    R.2.2 Grafika z pliku samochod.png ma przezroczyste tło

    ok. 3 min
    Polecenie z arkusza

    Plik samochod.jpg należy zapisać pod tą samą nazwą w formacie PNG z przezroczystym tłem

    JPEG nie ma przezroczystości. W GIMP-ie: Warstwa → Przezroczystość → Dodaj kanał alfa, różdżka z progiem około 50 i kliknięcie w białe tło (odblaski na karoserii zostają, bo nie stykają się z tłem), Delete, a na koniec Plik → Wyeksportuj jako samochod.png. Próg większy niż zero zdejmuje jasną obwódkę z pikseli JPEG przy krawędzi auta.

    Typowe błędy

    Zmiana samego rozszerzenia nazwy na .png nie zmienia formatu ani tła (R.2.2).

    Podgląd strony po tym kroku
    Podgląd strony po kroku 10
  11. Krok 11: Plik stacja.html: HTML5, język, kodowanie

    Kryteria:

    R.2.3 Witrynę internetową zapisano w plikach stacja.html oraz obliczenia.html oraz na przynajmniej jednej stronie zapisano jawnie standard kodowania polskich znaków i deklarację HTML5 <!DOCTYPE HTML> oraz zadeklarowano dla witryny język polski

    ok. 2 min
    Polecenie z arkusza

    Składa się ze stron o nazwach stacja.html oraz obliczenia.html zapisanych w języku HTML 5. Obie strony różnią się jedynie blokiem lewym. Jawnie zastosowany właściwy standard kodowania polskich znaków. Zadeklarowany język dla witryny: polski

    <!DOCTYPE html>, <html lang="pl"> i <meta charset="UTF-8"> jako pierwszy element <head> (R.2.3). Najpierw powstaje cała strona stacja.html; obliczenia.html będzie jej kopią z innym blokiem lewym - wspólne części piszesz raz.

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

    Kryteria:

    R.2.4 Nadano tytuł przynajmniej jednej strony: Stacja paliw

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Stacja paliw”

    <title> (R.2.4) i viewport - telefon nie pomniejsza strony do szerokości ekranu komputera.

    stacja.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>Stacja paliw</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (stacja.html)
  13. Krok 13: Podpięcie arkusza stylów

    Kryteria:

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

    Nazwa pliku: styl2.css - z cyfrą 2. Całe formatowanie pochodzi z tego pliku, bez atrybutów style (R.3.6).

    Typowe błędy

    Klucz odbiera R.3.6 także wtedy, gdy choć jeden selektor nie trafia w blok (np. kropka zamiast #).

    stacja.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (stacja.html)
  14. Krok 14: Bloki: baner, menu, lewy i prawy w main, stopka

    Kryteria:

    R.2.5 Układ przynajmniej jednej strony zdefiniowano dzieląc ją na bloki: baner, menu, lewy, prawy i stopka. Zastosowano znaczniki sekcji

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: blok banera, poniżej blok menu, poniżej blok lewy i prawy, na dole 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

    Baner to <header>, menu <nav>, stopka <footer>. Bloki lewy i prawy stoją we wspólnym <main> - to główna treść strony i zarazem pojemnik, który w CSS ustawi je obok siebie:

    • lewy <section id="info"> - na jednej stronie godziny otwarcia, na drugiej kalkulator,
    • prawy <aside id="photo"> - zdjęcie samochodu, czyli treść dodatkowa obok głównej.

    Identyfikatory mówią, co jest w bloku, a nie gdzie stoi (R.2.5).

    stacja.html HTML zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
        </header>
        <nav>
        </nav>
        <main>
            <section id="info">
            </section>
            <aside id="photo">
            </aside>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (stacja.html)
  15. Krok 15: Baner: nagłówek pierwszego stopnia

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku banera: nagłówek pierwszego stopnia o treści „Całodobowa stacja paliw”

    <h1> w <header>.

    stacja.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
        </nav>
        <main>
            <section id="info">
            </section>
            <aside id="photo">
            </aside>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (stacja.html)
  16. Krok 16: Menu: ikona home jako odnośnik

    ok. 1 min
    Polecenie z arkusza

    Obraz home.png, który jest odnośnikiem do strony stacja.html

    Obraz staje się odnośnikiem, gdy <img> stoi wewnątrz <a>. Odnośnik nie ma innego tekstu, więc tekst alternatywny opisuje cel odnośnika („Godziny otwarcia”), a nie wygląd ikony - czytnik ekranu przeczyta go jako nazwę odnośnika.

    stacja.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
        </nav>
        <main>
            <section id="info">
            </section>
            <aside id="photo">
            </aside>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (stacja.html)
  17. Krok 17: Menu: ikona dystrybutora jako odnośnik

    Kryteria:

    R.3.2 Na przynajmniej jednej stronie po kliknięciu obrazu home.png otwiera się strona stacja.html oraz po kliknięciu obrazu znak.png otwiera się strona obliczenia.html

    ok. 1 min
    Polecenie z arkusza

    Obraz znak.png, który jest odnośnikiem do strony obliczenia.html

    Tak samo jak ikona domu, z adresem drugiej strony. Kliknięcie ikony domu otwiera stronę z godzinami, ikony dystrybutora - stronę z obliczeniami (R.3.2); w podglądzie odnośniki są zablokowane, działają po otwarciu plików w przeglądarce.

    stacja.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
            <a href="obliczenia.html"><img src="znak.png" alt="Koszt paliwa"></a>
        </nav>
        <main>
            <section id="info">
            </section>
            <aside id="photo">
            </aside>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (stacja.html)
  18. Krok 18: Menu: odnośnik do kwerendy.txt

    Kryteria:

    R.3.3 Na przynajmniej jednej stronie po kliknięciu na odnośnik "Pobierz dokumenty" otwiera się lub pobiera plik kwerendy.txt

    ok. 1 min
    Polecenie z arkusza

    Odnośnik do pliku kwerendy.txt o treści: „Pobierz dokumenty”

    href z nazwą pliku leżącego w tym samym folderze - przeglądarka otworzy plik tekstowy albo zaproponuje jego pobranie; klucz uznaje oba zachowania (R.3.3).

    stacja.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
            <a href="obliczenia.html"><img src="znak.png" alt="Koszt paliwa"></a>
            <a href="kwerendy.txt">Pobierz dokumenty</a>
        </nav>
        <main>
            <section id="info">
            </section>
            <aside id="photo">
            </aside>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (stacja.html)
  19. Krok 19: Blok prawy: samochód

    Kryteria: ,

    R.2.8 Na przynajmniej jednej stronie umieszczono w bloku menu obraz home.png i znak.png oraz w bloku prawym obraz samochod w formacie JPG lub PNG

    R.2.9 Nadano dla obrazu samochod tekst alternatywny "samochód"

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku prawego: obraz samochod.png z tekstem alternatywnym „samochód”

    Plik PNG po usunięciu tła i tekst alternatywny z polską literą „ó”. Identyfikator car przyda się w CSS - obraz samochodu ma własne marginesy i obramowanie pod kursorem, a ikony w menu nie (R.2.8, R.2.9).

    stacja.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
            <a href="obliczenia.html"><img src="znak.png" alt="Koszt paliwa"></a>
            <a href="kwerendy.txt">Pobierz dokumenty</a>
        </nav>
        <main>
            <section id="info">
            </section>
            <aside id="photo">
                <img src="samochod.png" alt="samochód" id="car">
            </aside>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (stacja.html)
  20. Krok 20: Stopka

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: akapit (paragraf) o treści: „Stronę opracował: ”, oraz zawierający numer, którym został podpisany arkusz

    Akapit <p> w <footer>. Na egzaminie w miejscu imienia i nazwiska wpisujesz numer, którym podpisany jest arkusz (PESEL); tu stoi autor rozwiązania - „Bartosz Bryniarski”.

    stacja.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
            <a href="obliczenia.html"><img src="znak.png" alt="Koszt paliwa"></a>
            <a href="kwerendy.txt">Pobierz dokumenty</a>
        </nav>
        <main>
            <section id="info">
            </section>
            <aside id="photo">
                <img src="samochod.png" alt="samochód" id="car">
            </aside>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (stacja.html)
  21. Krok 21: stacja.html, blok lewy: nagłówek

    Kryteria:

    R.2.6 Dla przynajmniej jednej strony w banerze zapisano nagłówek h1: „Całodobowa stacja paliw”, w bloku lewym przynajmniej jeden z h2: "Godziny otwarcia stacji" lub „Orientacyjny koszt paliwa” oraz w stopce paragraf o treści: "Stronę opracował:" z numerem zdającego

    ok. 1 min
    Polecenie z arkusza

    Nagłówek drugiego stopnia o treści „Godziny otwarcia stacji”

    <h2> w bloku lewym. Strona ma już <h1> w banerze, <h2> w bloku lewym i akapit w stopce (R.2.6).

    stacja.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
            <a href="obliczenia.html"><img src="znak.png" alt="Koszt paliwa"></a>
            <a href="kwerendy.txt">Pobierz dokumenty</a>
        </nav>
        <main>
            <section id="info">
                <h2>Godziny otwarcia stacji</h2>
            </section>
            <aside id="photo">
                <img src="samochod.png" alt="samochód" id="car">
            </aside>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (stacja.html)
  22. Krok 22: stacja.html, blok lewy: tabela godzin otwarcia

    Kryteria:

    R.2.7 Na stronie stacja.html umieszczono tabelę o trzech kolumnach i trzech wierszach zgodną z obrazem 3 arkusza egzaminacyjnego, zastosowano znaczniki <table>, <tr>, <td>

    ok. 2 min
    Polecenie z arkusza

    Tabela 3x3, której komórki są wypełnione zgodnie z obrazem 3

    <table> z trzema wierszami <tr>, w każdym trzy komórki <td> (R.2.7). Godziny stoją w znacznikach <time> - przeglądarka i wyszukiwarka wiedzą, że to pora dnia, a wygląd się nie zmienia.

    Pierwszy wiersz („Dzień”, „Od”, „Do”) jest z natury nagłówkiem, ale zostaje w <td>: na obrazie 3 wygląda tak samo jak pozostałe, a <th> byłby pogrubiony i nie dostałby obramowania z reguły dla td, której wymaga klucz.

    stacja.html HTML zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
            <a href="obliczenia.html"><img src="znak.png" alt="Koszt paliwa"></a>
            <a href="kwerendy.txt">Pobierz dokumenty</a>
        </nav>
        <main>
            <section id="info">
                <h2>Godziny otwarcia stacji</h2>
                <table>
                    <tr><td>Dzień</td><td>Od</td><td>Do</td></tr>
                    <tr><td>Pn - Sb</td><td><time>6:00</time></td><td><time>24:00</time></td></tr>
                    <tr><td>Nd</td><td><time>7:00</time></td><td><time>24:00</time></td></tr>
                </table>
            </section>
            <aside id="photo">
                <img src="samochod.png" alt="samochód" id="car">
            </aside>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (stacja.html)
  23. Krok 23: obliczenia.html: kopia strony z innym blokiem lewym

    ok. 2 min
    Polecenie z arkusza

    Składa się ze stron o nazwach stacja.html oraz obliczenia.html zapisanych w języku HTML 5. Obie strony różnią się jedynie blokiem lewym

    Zapisz jako obliczenia.html - wszystko poza blokiem lewym zostaje, a zawartość bloku lewego zastępuje nagłówek drugiego stopnia „Orientacyjny koszt paliwa”.

    obliczenia.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
            <a href="obliczenia.html"><img src="znak.png" alt="Koszt paliwa"></a>
            <a href="kwerendy.txt">Pobierz dokumenty</a>
        </nav>
        <main>
            <section id="info">
                <h2>Orientacyjny koszt paliwa</h2>
            </section>
            <aside id="photo">
                <img src="samochod.png" alt="samochód" id="car">
            </aside>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (obliczenia.html)
  24. Krok 24: obliczenia.html: formularz i pole na rodzaj paliwa

    Kryteria:

    R.3.5 Przynajmniej jedno pole edycyjne jest typu numerycznego

    ok. 3 min
    Polecenie z arkusza

    Pole edycyjne typu numerycznego, z napisem nad polem: „Rodzaj paliwa (1-benzyna, 2-olej napędowy): ”

    • <form id="fuel-form"> - pola i przycisk w formularzu: przycisk zatwierdzi go także klawiszem Enter, a skrypt obsłuży jedno zdarzenie formularza. Formularz niczego nie wysyła na serwer - zatrzyma to skrypt,
    • novalidate - przeglądarka nie zablokuje kliknięcia własnym dymkiem z błędem; o złych danych powie skrypt,
    • para napis + pole we własnym bloku <div class="field"> zamiast <br>; „nad polem” ustawi jedna reguła CSS,
    • type="number" (R.3.5) i name="fuelType" - pod tą nazwą skrypt znajdzie pole w formularzu.
    obliczenia.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
            <a href="obliczenia.html"><img src="znak.png" alt="Koszt paliwa"></a>
            <a href="kwerendy.txt">Pobierz dokumenty</a>
        </nav>
        <main>
            <section id="info">
                <h2>Orientacyjny koszt paliwa</h2>
                <form id="fuel-form" novalidate>
                    <div class="field">
                        <label for="fuel-type">Rodzaj paliwa (1-benzyna, 2-olej napędowy): </label>
                        <input type="number" id="fuel-type" name="fuelType">
                    </div>
                </form>
            </section>
            <aside id="photo">
                <img src="samochod.png" alt="samochód" id="car">
            </aside>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (obliczenia.html)
  25. Krok 25: obliczenia.html: pole na liczbę litrów

    ok. 1 min
    Polecenie z arkusza

    Pole edycyjne typu numerycznego z napisem nad polem: „Ile litrów?”

    Drugie pole tego samego typu. min="0" i step="0.01" - strzałki pola nie schodzą poniżej zera i zmieniają wartość o setne części litra.

    obliczenia.html HTML zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
            <a href="obliczenia.html"><img src="znak.png" alt="Koszt paliwa"></a>
            <a href="kwerendy.txt">Pobierz dokumenty</a>
        </nav>
        <main>
            <section id="info">
                <h2>Orientacyjny koszt paliwa</h2>
                <form id="fuel-form" novalidate>
                    <div class="field">
                        <label for="fuel-type">Rodzaj paliwa (1-benzyna, 2-olej napędowy): </label>
                        <input type="number" id="fuel-type" name="fuelType">
                    </div>
                    <div class="field">
                        <label for="liters">Ile litrów?</label>
                        <input type="number" id="liters" name="liters" min="0" step="0.01">
                    </div>
                </form>
            </section>
            <aside id="photo">
                <img src="samochod.png" alt="samochód" id="car">
            </aside>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (obliczenia.html)
  26. Krok 26: obliczenia.html: przycisk OBLICZ

    Kryteria:

    R.2.10 Na stronie obliczenia.html w bloku lewym umieszczono dwa pola edycyjne oraz przycisk o treści: "OBLICZ"

    ok. 1 min
    Polecenie z arkusza

    Przycisk o treści „OBLICZ”

    <button type="submit"> zatwierdza formularz - kliknięciem albo klawiszem Enter w polu. W bloku lewym są już dwa pola i przycisk (R.2.10).

    obliczenia.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
            <a href="obliczenia.html"><img src="znak.png" alt="Koszt paliwa"></a>
            <a href="kwerendy.txt">Pobierz dokumenty</a>
        </nav>
        <main>
            <section id="info">
                <h2>Orientacyjny koszt paliwa</h2>
                <form id="fuel-form" novalidate>
                    <div class="field">
                        <label for="fuel-type">Rodzaj paliwa (1-benzyna, 2-olej napędowy): </label>
                        <input type="number" id="fuel-type" name="fuelType">
                    </div>
                    <div class="field">
                        <label for="liters">Ile litrów?</label>
                        <input type="number" id="liters" name="liters" min="0" step="0.01">
                    </div>
                    <button type="submit">OBLICZ</button>
                </form>
            </section>
            <aside id="photo">
                <img src="samochod.png" alt="samochód" id="car">
            </aside>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (obliczenia.html)
  27. Etap 3: Styl CSS

    Kroki 27-37 · po tym etapie masz 32 z 38 kryteriów (pkt)

    Krok 27: Plik styl2.css: zmienne, krój i wyśrodkowanie

    Kryteria:

    R.4.1 Ustawiono domyślne formatowanie wszystkich selektorów (*): krój czcionki Cambria, wyrównanie tekstu do środka (w przypadku wymienionych kilku czcionek Cambria jest wymieniona jako pierwsza)

    ok. 2 min
    Polecenie z arkusza

    Domyślne formatowanie wszystkich selektorów: krój czcionki Cambria, wyrównanie tekstu do środka

    Dwa kolory z arkusza w zmiennych - malinowy rgb(173, 20, 87) pojawi się w menu i w bloku prawym, więc zmiana odcienia to jedna linia. Selektor uniwersalny * z Cambrią na pierwszym miejscu (R.4.1) i krojami zapasowymi: gdy Cambrii nie ma w systemie, przeglądarka weźmie Georgię albo inny krój szeryfowy.

    styl2.css CSS nowy plik
    :root {
        --wine: rgb(120, 0, 46);
        --raspberry: rgb(173, 20, 87);
    }
    
    * {
        font-family: Cambria, Georgia, serif;
        text-align: center;
    }
    Podgląd strony po tym kroku (stacja.html)
  28. Krok 28: Baner i stopka

    Kryteria:

    R.4.8 Ustawiono rozmiar czcionki 150% dla bloku banera i stopki

    ok. 1 min
    Polecenie z arkusza

    Wspólne dla bloku banera i stopki: kolor tła rgb 120, 0, 46; biały kolor czcionki, marginesy wewnętrzne 5 px, rozmiar czcionki 150%

    Jedna reguła dla dwóch selektorów, kolor ze zmiennej. Kolor podany trzema liczbami zapisuje się funkcją rgb(120, 0, 46) - składowe czerwona, zielona i niebieska od 0 do 255 (R.4.8).

    styl2.css CSS zmienione: 8 linii
    :root {
        --wine: rgb(120, 0, 46);
        --raspberry: rgb(173, 20, 87);
    }
    
    * {
        font-family: Cambria, Georgia, serif;
        text-align: center;
    }
    
    header,
    footer {
        background-color: var(--wine);
        color: white;
        padding: 5px;
        font-size: 150%;
    }
    Podgląd strony po tym kroku (stacja.html)
  29. Krok 29: Blok menu

    ok. 1 min
    Polecenie z arkusza

    Dla bloku menu: kolor tła rgb 173, 20, 87; wyrównanie tekstu do lewej strony

    Selektor znacznika nav. Ikony i odnośnik są elementami liniowymi, więc ustawiają się od lewej krawędzi.

    styl2.css CSS zmienione: 5 linii
    :root {
        --wine: rgb(120, 0, 46);
        --raspberry: rgb(173, 20, 87);
    }
    
    * {
        font-family: Cambria, Georgia, serif;
        text-align: center;
    }
    
    header,
    footer {
        background-color: var(--wine);
        color: white;
        padding: 5px;
        font-size: 150%;
    }
    
    nav {
        background-color: var(--raspberry);
        text-align: left;
    }
    Podgląd strony po tym kroku (stacja.html)
  30. Krok 30: Blok lewy

    Kryteria:

    R.4.7 Ustawiono wyrównanie tekstu do lewej strony dla bloków menu i lewego

    ok. 1 min
    Polecenie z arkusza

    Dla bloku lewego: kolor tła Snow; kolor czcionki OliveDrab, szerokość 60%, wysokość 322 px, wyrównanie tekstu do lewej strony

    Snow i OliveDrab to nazwy kolorów CSS. Szerokości 60% tu nie ma: w siatce procent przy bloku liczyłby się od jego kolumny, więc trafi do definicji kolumn - klucz R.4.4 wprost to dopuszcza. Do lewej wyrównają się napisy przy polach; h2 zostaje na środku, bo reguła * działa na niego bezpośrednio (R.4.7: menu i blok lewy).

    styl2.css CSS zmienione: 7 linii
    :root {
        --wine: rgb(120, 0, 46);
        --raspberry: rgb(173, 20, 87);
    }
    
    * {
        font-family: Cambria, Georgia, serif;
        text-align: center;
    }
    
    header,
    footer {
        background-color: var(--wine);
        color: white;
        padding: 5px;
        font-size: 150%;
    }
    
    nav {
        background-color: var(--raspberry);
        text-align: left;
    }
    
    #info {
        background-color: Snow;
        color: OliveDrab;
        height: 322px;
        text-align: left;
    }
    Podgląd strony po tym kroku (stacja.html)
  31. Krok 31: Blok prawy

    Kryteria: ,

    R.4.2 Ustawiono kolor tła dla banera i stopki rgb(120, 0, 46), dla bloku menu i prawego rgb(173, 20, 87), dla bloku lewego Snow

    R.4.5 Ustawiono wysokość dla bloku lewego i prawego 322px

    ok. 1 min
    Polecenie z arkusza

    Dla bloku prawego: kolor tła rgb 173, 20, 87; szerokość 40%, wysokość 322 px

    Tło ze zmiennej i wysokość; szerokość 40% - w kolumnach siatki. Ustawione są już kolory tła wszystkich bloków (R.4.2) i wysokości bloków lewego i prawego (R.4.5).

    styl2.css CSS zmienione: 5 linii
    :root {
        --wine: rgb(120, 0, 46);
        --raspberry: rgb(173, 20, 87);
    }
    
    * {
        font-family: Cambria, Georgia, serif;
        text-align: center;
    }
    
    header,
    footer {
        background-color: var(--wine);
        color: white;
        padding: 5px;
        font-size: 150%;
    }
    
    nav {
        background-color: var(--raspberry);
        text-align: left;
    }
    
    #info {
        background-color: Snow;
        color: OliveDrab;
        height: 322px;
        text-align: left;
    }
    
    #photo {
        background-color: var(--raspberry);
        height: 322px;
    }
    Podgląd strony po tym kroku (stacja.html)
  32. Krok 32: Obraz samochodu: marginesy

    ok. 2 min
    Polecenie z arkusza

    Dla obrazu z samochodem: marginesy zewnętrzne 40 px, wewnętrzne 10 px

    Reguła dla identyfikatora #car - ikony w menu jej nie dostaną. Wysokość się zgadza: obraz ma 222 px, do tego 2 × 10 px marginesu wewnętrznego i 2 × 40 px zewnętrznego - razem 322 px, tyle co blok prawy. Przezroczysta ramka 1px dotted transparent rezerwuje miejsce na obramowanie z następnego kroku: bez niej ramka pojawiająca się pod kursorem przesuwa obraz o piksel. Jej 2 px wchodzą w dolny margines, który i tak jest niewidoczny.

    styl2.css CSS zmienione: 6 linii
    :root {
        --wine: rgb(120, 0, 46);
        --raspberry: rgb(173, 20, 87);
    }
    
    * {
        font-family: Cambria, Georgia, serif;
        text-align: center;
    }
    
    header,
    footer {
        background-color: var(--wine);
        color: white;
        padding: 5px;
        font-size: 150%;
    }
    
    nav {
        background-color: var(--raspberry);
        text-align: left;
    }
    
    #info {
        background-color: Snow;
        color: OliveDrab;
        height: 322px;
        text-align: left;
    }
    
    #photo {
        background-color: var(--raspberry);
        height: 322px;
    }
    
    #car {
        margin: 40px;
        padding: 10px;
        border: 1px dotted transparent;
    }
    Podgląd strony po tym kroku (stacja.html)
  33. Krok 33: Samochód pod kursorem

    Kryteria:

    R.4.10 Gdy kursor myszy znajdzie się na obrazie samochodu pojawia się jego obramowanie 1px dotted YellowGreen (dla pseudoklasy :hover)

    ok. 1 min
    Polecenie z arkusza

    Gdy kursor myszy znajdzie się na samochodzie pojawia się obramowanie kropkowane o szerokości 1 px i kolorze YellowGreen

    Pseudoklasa :hover, obramowanie dotted (kropkowane) - pełny zapis z arkusza, więc klucz widzi wprost wszystkie trzy wartości (R.4.10). Ramka otacza obraz razem z marginesem wewnętrznym 10 px.

    styl2.css CSS zmienione: 4 linie
    :root {
        --wine: rgb(120, 0, 46);
        --raspberry: rgb(173, 20, 87);
    }
    
    * {
        font-family: Cambria, Georgia, serif;
        text-align: center;
    }
    
    header,
    footer {
        background-color: var(--wine);
        color: white;
        padding: 5px;
        font-size: 150%;
    }
    
    nav {
        background-color: var(--raspberry);
        text-align: left;
    }
    
    #info {
        background-color: Snow;
        color: OliveDrab;
        height: 322px;
        text-align: left;
    }
    
    #photo {
        background-color: var(--raspberry);
        height: 322px;
    }
    
    #car {
        margin: 40px;
        padding: 10px;
        border: 1px dotted transparent;
    }
    
    #car:hover {
        border: 1px dotted YellowGreen;
    }
    Podgląd strony po tym kroku (stacja.html)
  34. Krok 34: Odnośniki

    Kryteria: ,

    R.4.3 Ustawiono biały kolor czcionki dla banera i stopki, OliveDrab dla bloku lewego i YellowGreen dla selektora a

    R.4.6 Ustawiono marginesy wewnętrzne (padding) 5px dla banera i stopki, 10px dla obrazu z samochodem, dla odnośnika: górny, dolny 0, lewy, prawy 50px oraz ustawiono marginesy zewnętrzne (margin) 40px dla obrazu z samochodem

    ok. 1 min
    Polecenie z arkusza

    Dla selektora odnośnika: marginesy wewnętrzne górny i dolny 0 px, lewy i prawy 50 px, kolor czcionki YellowGreen

    Selektor znacznika a - uwaga pod listą stylów wyklucza klasy. padding: 0 50px - pierwsza wartość dla góry i dołu, druga dla boków. Reguła działa na wszystkie trzy odnośniki menu, także te z ikonami. Ustawione są już wszystkie kolory czcionek (R.4.3) i marginesy (R.4.6).

    styl2.css CSS zmienione: 5 linii
    :root {
        --wine: rgb(120, 0, 46);
        --raspberry: rgb(173, 20, 87);
    }
    
    * {
        font-family: Cambria, Georgia, serif;
        text-align: center;
    }
    
    header,
    footer {
        background-color: var(--wine);
        color: white;
        padding: 5px;
        font-size: 150%;
    }
    
    nav {
        background-color: var(--raspberry);
        text-align: left;
    }
    
    #info {
        background-color: Snow;
        color: OliveDrab;
        height: 322px;
        text-align: left;
    }
    
    #photo {
        background-color: var(--raspberry);
        height: 322px;
    }
    
    #car {
        margin: 40px;
        padding: 10px;
        border: 1px dotted transparent;
    }
    
    #car:hover {
        border: 1px dotted YellowGreen;
    }
    
    a {
        padding: 0 50px;
        color: YellowGreen;
    }
    Podgląd strony po tym kroku (stacja.html)
  35. Krok 35: Tabela: obramowanie i szerokość

    Kryteria:

    R.4.9 Ustawiono dla tabeli i selektora td: obramowanie 1px solid OliveDrab

    ok. 1 min
    Polecenie z arkusza

    Dla selektora tabeli i komórki tabeli: obramowanie linią ciągłą o grubości 1 px i kolorze OliveDrab. Dodatkowo dla selektora tabeli: szerokość 90%

    Selektory znaczników table i td (R.4.9). Obramowanie tabeli i każdej komórki osobno daje podwójne linie, jak na obrazie 3 - dlatego nie ma tu border-collapse. Szerokość 90% liczy się od bloku lewego.

    Typowe błędy

    Klucz (R.4.9) uznaje tylko selektory table i td - reguła dla klasy tabeli albo #info table nie jest liczona.

    styl2.css CSS zmienione: 9 linii
    :root {
        --wine: rgb(120, 0, 46);
        --raspberry: rgb(173, 20, 87);
    }
    
    * {
        font-family: Cambria, Georgia, serif;
        text-align: center;
    }
    
    header,
    footer {
        background-color: var(--wine);
        color: white;
        padding: 5px;
        font-size: 150%;
    }
    
    nav {
        background-color: var(--raspberry);
        text-align: left;
    }
    
    #info {
        background-color: Snow;
        color: OliveDrab;
        height: 322px;
        text-align: left;
    }
    
    #photo {
        background-color: var(--raspberry);
        height: 322px;
    }
    
    #car {
        margin: 40px;
        padding: 10px;
        border: 1px dotted transparent;
    }
    
    #car:hover {
        border: 1px dotted YellowGreen;
    }
    
    a {
        padding: 0 50px;
        color: YellowGreen;
    }
    
    table,
    td {
        border: 1px solid OliveDrab;
    }
    
    table {
        width: 90%;
    }
    Podgląd strony po tym kroku (stacja.html)
  36. Krok 36: Formularz: napis nad polem, wyrównanie do lewej

    ok. 1 min
    Polecenie z arkusza

    Pole edycyjne typu numerycznego, z napisem nad polem: „Rodzaj paliwa (1-benzyna, 2-olej napędowy): ”. Pole edycyjne typu numerycznego z napisem nad polem: „Ile litrów?”

    <label> jest elementem liniowym i stanąłby obok pola. display: block zamienia go w blok na całą szerokość - pole spada pod napis, a następny <div> zaczyna kolejną parę od nowej linii.

    Druga reguła przywraca wyrównanie do lewej. Selektor * z pierwszej reguły daje wyśrodkowanie każdemu elementowi z osobna, więc formularz, bloki <div> i napisy nie dziedziczą wyrównania do lewej z bloku #info - a na obrazie 2 pola stoją przy lewej krawędzi. text-align: inherit każe im wziąć wyrównanie od rodzica, czyli ostatecznie od bloku lewego. W wersji podstawowej tego problemu nie ma, bo napisy i pola stoją wprost w bloku lewym, bez własnych bloków.

    styl2.css CSS zmienione: 9 linii
    :root {
        --wine: rgb(120, 0, 46);
        --raspberry: rgb(173, 20, 87);
    }
    
    * {
        font-family: Cambria, Georgia, serif;
        text-align: center;
    }
    
    header,
    footer {
        background-color: var(--wine);
        color: white;
        padding: 5px;
        font-size: 150%;
    }
    
    nav {
        background-color: var(--raspberry);
        text-align: left;
    }
    
    #info {
        background-color: Snow;
        color: OliveDrab;
        height: 322px;
        text-align: left;
    }
    
    #photo {
        background-color: var(--raspberry);
        height: 322px;
    }
    
    #car {
        margin: 40px;
        padding: 10px;
        border: 1px dotted transparent;
    }
    
    #car:hover {
        border: 1px dotted YellowGreen;
    }
    
    a {
        padding: 0 50px;
        color: YellowGreen;
    }
    
    table,
    td {
        border: 1px solid OliveDrab;
    }
    
    table {
        width: 90%;
    }
    
    #fuel-form,
    #fuel-form * {
        text-align: inherit;
    }
    
    .field label {
        display: block;
    }
    Podgląd strony po tym kroku (obliczenia.html)
  37. Krok 37: Układ bloków: siatka z kolumnami 60% i 40%

    Kryteria: ,

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

    R.4.4 Ustawiono szerokość dla bloku lewego 60% i prawego 40% (width lub grid-template- columns lub flex) oraz dla selektora table 90%

    ok. 2 min
    Polecenie z arkusza

    Podział strony na bloki: blok banera, poniżej blok menu, poniżej blok lewy i prawy, na dole 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

    display: grid na <main> i grid-template-columns: 60% 40% - dwie kolumny o szerokościach z arkusza: blok lewy trafia do pierwszej, prawy do drugiej, w kolejności z kodu. Ten krok domyka szerokości (R.4.4: 60% i 40% w kolumnach siatki, 90% tabeli).

    Baner, menu i stopka są poza siatką, więc stoją nad nią i pod nią same z siebie - bez float nie ma clear (R.3.1).

    Typowe błędy

    width: 60% przy bloku w siatce liczy się od kolumny: blok miałby 60% z 60% strony - szerokości podaje się w grid-template-columns.

    styl2.css CSS zmienione: 5 linii
    :root {
        --wine: rgb(120, 0, 46);
        --raspberry: rgb(173, 20, 87);
    }
    
    * {
        font-family: Cambria, Georgia, serif;
        text-align: center;
    }
    
    header,
    footer {
        background-color: var(--wine);
        color: white;
        padding: 5px;
        font-size: 150%;
    }
    
    nav {
        background-color: var(--raspberry);
        text-align: left;
    }
    
    #info {
        background-color: Snow;
        color: OliveDrab;
        height: 322px;
        text-align: left;
    }
    
    #photo {
        background-color: var(--raspberry);
        height: 322px;
    }
    
    #car {
        margin: 40px;
        padding: 10px;
        border: 1px dotted transparent;
    }
    
    #car:hover {
        border: 1px dotted YellowGreen;
    }
    
    a {
        padding: 0 50px;
        color: YellowGreen;
    }
    
    table,
    td {
        border: 1px solid OliveDrab;
    }
    
    table {
        width: 90%;
    }
    
    #fuel-form,
    #fuel-form * {
        text-align: inherit;
    }
    
    .field label {
        display: block;
    }
    
    main {
        display: grid;
        grid-template-columns: 60% 40%;
    }
    Podgląd strony po tym kroku (obliczenia.html)
  38. Etap 4: Skrypt JavaScript

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

    Krok 38: Plik obliczenia.js i obsługa przycisku OBLICZ

    Kryteria: ,

    R.3.4 Po wciśnięciu przycisku OBLICZ jest wywołana funkcja ze skryptu

    R.5.1 Skrypt napisano w języku wykonywanym po stronie przeglądarki, zawiera on przynajmniej jedną instrukcję zapisaną poprawnie składniowo

    ok. 3 min
    Polecenie z arkusza

    Skrypt: Napisany w języku wykonywanym po stronie przeglądarki. Skrypt uruchamia się po wciśnięciu przycisku OBLICZ na stronie obliczenia.html

    Język wykonywany po stronie przeglądarki to JavaScript. Skrypt stoi w osobnym pliku obliczenia.js, podpiętym w <head> strony obliczenia.html atrybutem defer: przeglądarka pobiera plik równolegle ze stroną, a wykonuje go dopiero, gdy cały HTML jest już wczytany - formularz na pewno istnieje.

    • const form - formularz znaleziony raz, po identyfikatorze,
    • form.addEventListener('submit', calculateCost) - kliknięcie OBLICZ (albo Enter w polu) wywołuje funkcję; nazwa funkcji bez nawiasów, bo przekazujesz samą funkcję, a nie wynik jej wywołania (R.3.4, R.5.1),
    • event.preventDefault() - formularz nie przeładuje strony; zostaje sama praca skryptu.
    obliczenia.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
        <script src="obliczenia.js" defer></script>
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
            <a href="obliczenia.html"><img src="znak.png" alt="Koszt paliwa"></a>
            <a href="kwerendy.txt">Pobierz dokumenty</a>
        </nav>
        <main>
            <section id="info">
                <h2>Orientacyjny koszt paliwa</h2>
                <form id="fuel-form" novalidate>
                    <div class="field">
                        <label for="fuel-type">Rodzaj paliwa (1-benzyna, 2-olej napędowy): </label>
                        <input type="number" id="fuel-type" name="fuelType">
                    </div>
                    <div class="field">
                        <label for="liters">Ile litrów?</label>
                        <input type="number" id="liters" name="liters" min="0" step="0.01">
                    </div>
                    <button type="submit">OBLICZ</button>
                </form>
            </section>
            <aside id="photo">
                <img src="samochod.png" alt="samochód" id="car">
            </aside>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    obliczenia.js JavaScript nowy plik
    const form = document.getElementById('fuel-form');
    
    function calculateCost(event) {
        event.preventDefault();
    }
    
    form.addEventListener('submit', calculateCost);
    Podgląd strony po tym kroku (obliczenia.html)
  39. Krok 39: Skrypt: wartości z obu pól

    Kryteria:

    R.5.2 Skrypt pobiera wartości z obu pól edycyjnych (.value)

    ok. 2 min
    Polecenie z arkusza

    Skrypt pobiera wartości z obu pól edycyjnych

    form.elements zawiera pola formularza pod ich nazwami (name), a zapis const { fuelType, liters } = ... wyjmuje oba naraz do zmiennych. Właściwość .value oddaje wpisaną wartość - zawsze jako tekst, także w polu liczbowym - więc Number(...) zamienia ją od razu na liczbę (R.5.2). const zamiast let: te wartości już się w funkcji nie zmienią.

    obliczenia.js JavaScript zmienione: 3 linie
    const form = document.getElementById('fuel-form');
    
    function calculateCost(event) {
        event.preventDefault();
        const { fuelType, liters } = form.elements;
        const type = Number(fuelType.value);
        const amount = Number(liters.value);
    }
    
    form.addEventListener('submit', calculateCost);
    Podgląd strony po tym kroku (obliczenia.html)
  40. Krok 40: Skrypt: cennik w obiekcie i koszt

    Kryteria:

    R.5.3 Koszt paliwa jest obliczony jako iloczyn liczby litrów i wartości 4 (gdy rodzaj paliwa = 1) lub wartości 3.5 (gdy rodzaj paliwa = 2)

    ok. 3 min
    Polecenie z arkusza

    Następnie oblicza koszt paliwa ze względu na rodzaj i liczbę litrów uwzględniając: gdy rodzaj paliwa jest równy 1 – koszt jednego litra paliwa wynosi 4 zł, gdy rodzaj paliwa jest równy 2 – koszt jednego litra paliwa wynosi 3,5 zł

    Zamiast drabinki if / else if cennik stoi w jednym obiekcie PRICES na górze pliku: rodzaj paliwa jest kluczem, cena za litr - wartością. PRICES[type] odczytuje cenę dla wpisanego rodzaju, a koszt to iloczyn liczby litrów i tej ceny: 4 zł dla rodzaju 1, 3.5 zł dla rodzaju 2 (R.5.3). Nowy rodzaj paliwa (np. LPG) to jedna pozycja w obiekcie, bez nowego warunku.

    W kodzie ułamek pisze się z kropką: 3.5 - zapis 3,5 w JavaScripcie to nie liczba.

    Typowe błędy

    Egzaminator sprawdza R.5.3 i R.5.4 w kodzie - obiekt z cenami i mnożenie muszą być czytelne. Jeśli wolisz if / else if z porównaniem do 1 i 2 (wersja podstawowa), klucz uzna to tak samo.

    obliczenia.js JavaScript zmienione: 2 linie
    const PRICES = { 1: 4, 2: 3.5 };    // zł za litr: 1 - benzyna, 2 - olej napędowy
    const form = document.getElementById('fuel-form');
    
    function calculateCost(event) {
        event.preventDefault();
        const { fuelType, liters } = form.elements;
        const type = Number(fuelType.value);
        const amount = Number(liters.value);
        const cost = amount * PRICES[type];
    }
    
    form.addEventListener('submit', calculateCost);
    Podgląd strony po tym kroku (obliczenia.html)
  41. Krok 41: Skrypt: inny rodzaj paliwa

    Kryteria:

    R.5.4 Gdy podano inny rodzaj paliwa niż 1 lub 2 to koszt paliwa = 0

    ok. 2 min
    Polecenie z arkusza

    W każdym innym przypadku koszt paliwa wynosi 0 zł

    Dla rodzaju spoza obiektu (3, 0, puste pole) PRICES[type] zwraca undefined, a mnożenie przez undefined daje NaN. Operator ?? podstawia wtedy 0 - cena 0 zł, więc koszt też 0 (R.5.4). ?? reaguje tylko na brak wartości (undefined, null), a nie na zero czy pusty napis jak ||.

    obliczenia.js JavaScript zmienione: 2 linie
    const PRICES = { 1: 4, 2: 3.5 };    // zł za litr: 1 - benzyna, 2 - olej napędowy
    const form = document.getElementById('fuel-form');
    
    function calculateCost(event) {
        event.preventDefault();
        const { fuelType, liters } = form.elements;
        const type = Number(fuelType.value);
        const amount = Number(liters.value);
        const price = PRICES[type] ?? 0;    // każdy inny rodzaj: 0 zł
        const cost = amount * price;
    }
    
    form.addEventListener('submit', calculateCost);
    Podgląd strony po tym kroku (obliczenia.html)
  42. Krok 42: Skrypt: wynik pod przyciskiem

    Kryteria:

    R.5.5 Skrypt wyświetla wynik pod przyciskiem OBLICZ według wzoru: „koszt paliwa: <wartość> zł”, gdzie <wartość> oznacza obliczony wcześniej koszt paliwa

    ok. 3 min
    Polecenie z arkusza

    Następnie skrypt wyświetla wynik działania pod przyciskiem OBLICZ według wzoru: „koszt paliwa: <wartość> zł”, gdzie <wartość> oznacza obliczony wcześniej koszt paliwa.

    • pod przyciskiem, w akapicie wewnątrz formularza, dochodzi <output> - znacznik HTML przeznaczony na wynik obliczeń; atrybut for wskazuje pola, z których wynik powstaje, a czytnik ekranu ogłasza zmianę jego treści,
    • wynik trafia tam przez textContent (zwykły tekst, bez interpretowania jako HTML) i szablon tekstowy w odwrotnych apostrofach: ${...} wstawia wartość w miejsce wzoru (R.5.5),
    • Intl.NumberFormat('pl-PL', ...) zapisuje kwotę po polsku, zawsze z dwoma miejscami po przecinku. Samo mnożenie 4,1 × 3,5 daje w JavaScripcie 14.349999999999998 - liczby z ułamkiem komputer przechowuje dwójkowo i nie każdą zapisze dokładnie; formatowanie pokazuje „14,35”.

    Sprawdzone w Chrome: rodzaj 1 i 10 litrów - „koszt paliwa: 40,00 zł”, rodzaj 2 i 3 litry - „10,50 zł”, rodzaj 3 - „0,00 zł”, rodzaj 01 traktowany jak 1. Adres strony się nie zmienia - formularz nie przeładował strony.

    obliczenia.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>Stacja paliw</title>
        <link rel="stylesheet" href="styl2.css">
        <script src="obliczenia.js" defer></script>
    </head>
    <body>
        <header>
            <h1>Całodobowa stacja paliw</h1>
        </header>
        <nav>
            <a href="stacja.html"><img src="home.png" alt="Godziny otwarcia"></a>
            <a href="obliczenia.html"><img src="znak.png" alt="Koszt paliwa"></a>
            <a href="kwerendy.txt">Pobierz dokumenty</a>
        </nav>
        <main>
            <section id="info">
                <h2>Orientacyjny koszt paliwa</h2>
                <form id="fuel-form" novalidate>
                    <div class="field">
                        <label for="fuel-type">Rodzaj paliwa (1-benzyna, 2-olej napędowy): </label>
                        <input type="number" id="fuel-type" name="fuelType">
                    </div>
                    <div class="field">
                        <label for="liters">Ile litrów?</label>
                        <input type="number" id="liters" name="liters" min="0" step="0.01">
                    </div>
                    <button type="submit">OBLICZ</button>
                    <p><output id="result" for="fuel-type liters"></output></p>
                </form>
            </section>
            <aside id="photo">
                <img src="samochod.png" alt="samochód" id="car">
            </aside>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    obliczenia.js JavaScript zmienione: 3 linie
    const PRICES = { 1: 4, 2: 3.5 };    // zł za litr: 1 - benzyna, 2 - olej napędowy
    const PLN = new Intl.NumberFormat('pl-PL', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    const form = document.getElementById('fuel-form');
    const result = document.getElementById('result');
    
    function calculateCost(event) {
        event.preventDefault();
        const { fuelType, liters } = form.elements;
        const type = Number(fuelType.value);
        const amount = Number(liters.value);
        const price = PRICES[type] ?? 0;    // każdy inny rodzaj: 0 zł
        const cost = amount * price;
        result.textContent = `koszt paliwa: ${PLN.format(cost)} zł`;
    }
    
    form.addEventListener('submit', calculateCost);
    Podgląd strony po tym kroku (obliczenia.html)
  43. Krok 43: Skrypt: pusta albo ujemna liczba litrów

    ok. 2 min

    Dodatek spoza arkusza - klucz go nie ocenia. Bez sprawdzenia skrypt liczy wszystko, co dostanie: −5 litrów benzyny daje „koszt paliwa: -20,00 zł”, a puste pole - „0,00 zł”, jakby tankowanie było darmowe (oba sprawdzone w Chrome). Teraz przy pustym polu albo liczbie nie większej od zera skrypt wypisuje komunikat i kończy funkcję instrukcją return. Atrybut min="0" tego nie załatwi: ustawia tylko strzałki pola, a liczbę z klawiatury da się wpisać dowolną.

    Inny rodzaj paliwa dalej daje 0 zł, bo tak każe arkusz (R.5.4).

    obliczenia.js JavaScript zmienione: 4 linie
    const PRICES = { 1: 4, 2: 3.5 };    // zł za litr: 1 - benzyna, 2 - olej napędowy
    const PLN = new Intl.NumberFormat('pl-PL', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    const form = document.getElementById('fuel-form');
    const result = document.getElementById('result');
    
    function calculateCost(event) {
        event.preventDefault();
        const { fuelType, liters } = form.elements;
        const type = Number(fuelType.value);
        const amount = Number(liters.value);
        if (liters.value === '' || amount <= 0) {
            result.textContent = 'Podaj liczbę litrów większą od zera.';
            return;
        }
        const price = PRICES[type] ?? 0;    // każdy inny rodzaj: 0 zł
        const cost = amount * price;
        result.textContent = `koszt paliwa: ${PLN.format(cost)} zł`;
    }
    
    form.addEventListener('submit', calculateCost);
    Podgląd strony po tym kroku (obliczenia.html)
  44. Etap 5: Porównanie z wersją podstawową

    Krok 44 · po tym etapie masz 38 z 38 kryteriów (pkt)

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

    ok. 3 min

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

    wersja podstawowawersja nowoczesna
    układfloat: left bloków, clear stopki<main> z siatką 60% 40%
    bloki#left, #right#info, <aside id="photo">
    kolorywpisane w każdą regułęzmienne CSS
    obraz pod kursorempojawiająca się ramka przesuwa obraz o pikselprzezroczysta ramka rezerwuje miejsce
    pola<br> po napisach, bez formularza<form novalidate>, bloki <div>, Enter działa
    skrypt<script> na końcu strony, onclickplik obliczenia.js z defer, zdarzenie submit
    cenyif / else if / elseobiekt PRICES i ?? 0
    wynikinnerHTML w akapicie, 10.5textContent w <output>, 10,50

    Na egzaminie wersja podstawowa trzyma się elementów z tabeli DOM na ostatniej stronie arkusza (getElementById, .value, innerHTML, onclick) i łatwiej ją napisać bez dokumentacji pod ręką. Nowoczesna daje czytelniejszy kod i poprawnie zapisaną kwotę. Obie spełniają te same kryteria.

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

  45. Etap 6: Oddanie pracy

    Krok 45 · po tym etapie masz 38 z 38 kryteriów (pkt)

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

    ok. 5 min
    Polecenie z arkusza

    Po zakończeniu pracy utwórz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowałeś poprawność działania witryny. Umieść go w folderze z numerem, którym został podpisany arkusz. Nagraj płytę z rezultatami pracy. W folderze z numerem, którym został podpisany arkusz powinny znajdować się pliki: home.png, import.png, kw1.jpg, kw2.jpg, kw3.jpg, kw4.jpg, kw5.jpg, kwerendy.txt, obliczenia.html, przeglądarka.txt, samochod.png, stacja.html, styl2.css, znak.png, ewentualnie inne przygotowane pliki.

    W przeglądarka.txt nazwa przeglądarki, w której sprawdzane były strony. Do listy z arkusza dochodzi obliczenia.js - bez niego przycisk OBLICZ nic nie zrobi („ewentualnie inne przygotowane pliki”). Nagraj płytę, sprawdź jej odczyt i opisz ją numerem zdającego.

    Typowe błędy

    Pominięty obliczenia.js na płycie - skrypt nie działa, a R.5 trzeba by oceniać tylko w kodzie, którego egzaminator nie dostał.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

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

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.