Przejdź do treści
School IT / Przestrzeń do nauki

Obrazy i pliki statyczne

Plakat wydarzenia, logo szkoły, ikona — wszystko to są pliki, których Angular nie kompiluje, tylko podaje przeglądarce bez zmian. Trzeba wiedzieć, gdzie je położyć, jak zapisać adres i co zrobić, żeby strona nie skakała podczas wczytywania.

Angular 22 folder public img [src] alt width/height card-img-top 45 min
CEL LEKCJI

Czego się dziś nauczysz

  • Umieścisz obrazek w folderze public i zapiszesz poprawny adres zaczynający się od /.
  • Wyjaśnisz, dlaczego pliki z public nie przechodzą przez kompilator.
  • Podasz adres obrazka z pola klasy przez [src], a opis przez [alt].
  • Napiszesz alt, który opisuje treść obrazu.
  • Podasz width i height, żeby strona nie przeskakiwała przy wczytywaniu.
  • Znajdziesz błąd 404 w narzędziach przeglądarki, gdy obrazka brakuje.
  • Wstawisz obrazek do karty Bootstrapa i dopasujesz go do szerokości kolumny.

Przygotowanie: lekcje 05 i 06 — umiesz pokazać wartość pola i przekazać ją do właściwości elementu. Przewidywany czas: 45 min z zadaniami.

Obrazki do przykładów to pliki turniej.svg, roboty.svg i druk3d.svg — dostaniesz je od nauczyciela. Możesz też zapisać pod tymi nazwami dowolne własne obrazki (.svg, .png albo .jpg — wtedy zmień rozszerzenie w adresie).

TEORIA

Dlaczego obrazki mają osobny folder

Pliki z folderu src przechodzą przez kompilator: TypeScript zamienia się w JavaScript, szablony w kod. Z obrazkiem nie ma czego kompilować — ma po prostu trafić do przeglądarki taki, jaki jest.

Dlatego istnieje folder public (obok src, nie w nim). Wszystko, co w nim położysz, serwer podaje bez zmian, a ng build kopiuje do gotowej aplikacji. Leży tam już favicon.ico — ikona karty przeglądarki. Ten sam mechanizm obsłuży plik PDF z regulaminem i plik JSON z danymi, który wczytamy w lekcji 36.

gdzie leży plik
klub-gier/
  public/
    favicon.ico
    img/
      turniej.svg     ← tutaj (folder img utwórz sam)
      roboty.svg
      druk3d.svg
  src/
    app/
Plik w projekcieAdres w src
public/img/turniej.svg/img/turniej.svg
public/favicon.ico/favicon.ico
public/dokumenty/regulamin.pdf/dokumenty/regulamin.pdf

Słowa public nie ma w adresie

Folder public jest korzeniem serwera — adres zaczyna się od ukośnika i od razu od tego, co leży w środku. src="public/img/turniej.svg" to najczęstsza pomyłka tej lekcji.

TEORIA

Dwie zasady dobrego obrazka

alt opisuje treść

Tekst alternatywny czyta program dla osób niewidomych, pokazuje go przeglądarka, gdy obrazek się nie wczytał, i bierze pod uwagę wyszukiwarka. „Plakat turnieju retro” niesie informację. „obrazek” nie niesie żadnej. Obrazek czysto ozdobny dostaje pusty alt="" — czytnik go wtedy pominie.

width i height rezerwują miejsce

Przeglądarka, znając wymiary, zostawia puste pole, zanim plik dotrze. Bez tego reszta strony przeskakuje w chwili wczytania obrazka. Liczby w atrybutach to piksele, bez jednostki.

Obrazek dopasowany do kolumny

W siatce i w karcie szerokość wyznacza kolumna, a nie liczba w width. Bootstrap ma na to klasy: img-fluid (obrazek nigdy nie jest szerszy niż rodzic) i card-img-top (obrazek na całą szerokość karty, z zaokrąglonymi górnymi rogami). width i height zostawiasz — przeglądarka liczy z nich proporcje i nadal rezerwuje miejsce.

PRZYKŁAD 1

Gdzie wrzucić obrazek

Utwórz folder public/img i skopiuj do niego trzy obrazki. Adres w szablonie zaczyna się od ukośnika.

src/app/nowa-07-1/demo.ts — pełny plik
import { Component } from '@angular/core';

@Component({
    selector: 'app-demo',
    imports: [],
    templateUrl: './demo.html'
})
export class Demo {

}
src/app/nowa-07-1/demo.html — pełny plik
<div class="p-3">
  <img src="/img/turniej.svg" alt="Plakat turnieju retro" width="220" height="140">
</div>
wynik w przeglądarce
[ fioletowy plakat „Turniej retro, piątek, sala 12” — 220 × 140 ]

Klasa Demo jest pusta — obrazek ze stałym adresem nie potrzebuje żadnych danych.

Zatrzymaj się

Wpisz w pasku adresu przeglądarki localhost:4200/img/turniej.svg. Zobaczysz sam obrazek — dowód, że plik jest podawany niezależnie od aplikacji.

PRZYKŁAD 2

Adres obrazka z pola klasy

Skoro adres to zwykły tekst, może pochodzić z klasy — a wtedy przydają się nawiasy kwadratowe z lekcji 06.

src/app/nowa-07-2/demo.ts — pełny plik
import { Component } from '@angular/core';

@Component({
    selector: 'app-demo',
    imports: [],
    templateUrl: './demo.html'
})
export class Demo {
    readonly plakat = '/img/roboty.svg';
    readonly opis = 'Plakat Nocy robotów';
}
src/app/nowa-07-2/demo.html — pełny plik
<div class="card m-3" style="width: 16rem">
  <img [src]="plakat" [alt]="opis" class="card-img-top" width="240" height="150">
  <div class="card-body">
    <h5 class="card-title">Noc robotów</h5>
  </div>
</div>
wynik w przeglądarce
┌────────────────────┐
│ [plakat robotów]   │
│ Noc robotów        │
└────────────────────┘

Obrazek jest w karcie, u góry, dzięki klasie card-img-top. Zmień wartość pola plakat na '/img/druk3d.svg' i zapisz.

Zatrzymaj się

Zapis src="{{ plakat }}" też by zadziałał — adres to przecież tekst. Dlaczego mimo to warto przyzwyczaić się do [src]? Przypomnij sobie przycisk z disabled z lekcji 06.

PRZYKŁAD 3

Obrazek, którego nie ma

Zły adres nie zatrzymuje aplikacji i nie daje błędu w terminalu. To dlatego tak łatwo go przeoczyć.

src/app/nowa-07-3/demo.ts — pełny plik
import { Component } from '@angular/core';

@Component({
    selector: 'app-demo',
    imports: [],
    templateUrl: './demo.html'
})
export class Demo {
    readonly zly = '/img/nie-ma-takiego.svg';
    readonly dobry = '/img/druk3d.svg';
}
src/app/nowa-07-3/demo.html — pełny plik
<div class="p-3">
  <p>Poprawny adres:</p>
  <img [src]="dobry" alt="Warsztat druku 3D" width="220" height="140">

  <p class="mt-3">Błędny adres — zobacz konsolę (F12):</p>
  <img [src]="zly" alt="Tego pliku nie ma" width="220" height="140">
</div>
konsola przeglądarki (F12 → Console)
GET http://localhost:4200/img/nie-ma-takiego.svg 404 (Not Found)

Drugi obrazek pokazuje ikonę uszkodzonego pliku i tekst z alt. W zakładce Network (z filtrem Img) ten plik jest zaznaczony na czerwono ze statusem 404.

Zatrzymaj się

Tekst z alt pojawił się, bo obrazka nie ma. Kto jeszcze korzysta z tego tekstu, gdy obrazek wczytał się poprawnie?

PRZYKŁAD 4

Szerokość, wysokość i przeskakująca strona

Dwa atrybuty, o których początkujący zapominają — a różnicę widać gołym okiem przy wolnym łączu.

src/app/nowa-07-4/demo.ts — pełny plik
import { Component } from '@angular/core';

@Component({
    selector: 'app-demo',
    imports: [],
    templateUrl: './demo.html'
})
export class Demo {

}
src/app/nowa-07-4/demo.html — pełny plik
<div class="p-3">
  <p>Z podanymi wymiarami — miejsce jest zarezerwowane od początku:</p>
  <img src="/img/turniej.svg" alt="Turniej retro" width="220" height="140">
  <p class="mt-3">Bez wymiarów — tekst pod spodem podskoczy po wczytaniu:</p>
  <img src="/img/roboty.svg" alt="Noc robotów">
  <p>Ten akapit jest pod obrazkiem.</p>
</div>
co zobaczysz przy spowolnionym łączu
1. obrazek: puste miejsce 220 × 140 od początku, potem plakat
2. obrazek: brak miejsca — po wczytaniu akapit pod nim „zjeżdża” w dół

W narzędziach przeglądarki (F12 → Network) zaznacz Disable cache, włącz Slow 4G i odśwież stronę. Pierwszy obrazek ma zarezerwowane miejsce, drugi je sobie „wywalcza” i przesuwa tekst. Na koniec przywróć No throttling.

Zatrzymaj się

Drugi obrazek po wczytaniu jest dwa razy większy niż pierwszy. Skąd przeglądarka wzięła jego rozmiar, skoro nie podałeś width i height?

ELEMENTY WBUDOWANE

Zestawienie elementów

ElementZnaczenieUwagi
folder publicpliki podawane bez zmianObok src; jest korzeniem adresów.
src="/img/plik.svg"stały adres obrazkaOd ukośnika, bez słowa public.
[src]="pole"adres z pola klasyMożna sklejać: [src]="'/img/' + nazwa".
alt / [alt]opis treści obrazuOzdobnik: alt="".
width, heightwymiary w pikselachRezerwują miejsce przed wczytaniem.
img-fluidobrazek nie szerszy niż rodzicDo obrazków w kolumnach siatki.
card-img-topobrazek na górze kartyPierwszy element w card, przed card-body.
rounded, rounded-circlezaokrąglone rogi, kołoBootstrap; np. zdjęcie profilowe.
F12 → Network → Imglista pobranych obrazkówStatus 404 = brak pliku.
NgOptimizedImagedyrektywa do obrazków w dużych projektachNie potrzebujemy jej w kursie; warto znać nazwę.
CZĘSTE BŁĘDY

Zanim utkniesz

ZapisProblem
src="public/img/a.svg"404. Słowa public nie ma w adresie — ten folder jest korzeniem.
Obrazek w src/img albo src/assets404. Pliki z src nie są podawane przeglądarce. Do Angulara 17 domyślny był folder src/assets; od wersji 18 jest public.
Plik skopiowany do public, a nadal 404Sprawdź dokładnie nazwę i rozszerzenie (.svg czy .png). Na serwerze szkolnym wielkość liter ma znaczenie: Turniej.svg to inny plik niż turniej.svg.
Brak atrybutu altKompilator nie protestuje, ale czytnik ekranu nie ma czego przeczytać, a przy 404 nie widać, co miało tam być.
alt="obrazek"Tekst bez treści. alt opisuje, co przedstawia obraz.
[src]="/img/a.svg"Błąd składni: w nawiasach kwadratowych stoi kod. Stały adres bez nawiasów: src="/img/a.svg".
width="220px"Atrybut przyjmuje samą liczbę pikseli, bez jednostki.
ZADANIA

Zadania

ZAD 1Trzy plakaty w rzędzie★☆☆

Pokaż trzy plakaty obok siebie w siatce Bootstrapa (na wąskim ekranie jeden pod drugim). Każdy obrazek ma mieć sensowny alt, wymiary i klasę img-fluid.

Kryterium sukcesu: trzy obrazki stoją w rzędzie, mieszczą się w kolumnach, a po zwężeniu okna układają się jeden pod drugim.

Podpowiedź

Siatkę masz w lekcji 03: container → row g-3 → trzy razy col-12 col-md-4.

ZAD 2Logo w nagłówku★☆☆

Dodaj do public/img logo szkoły (dowolny obrazek) i wstaw je do komponentu naglowek z lekcji 04, przed nazwą klubu, w wysokości 40 pikseli. Zmień też ikonę karty przeglądarki, podmieniając plik public/favicon.ico.

Kryterium sukcesu: logo stoi w ciemnym pasku obok nazwy, a karta przeglądarki pokazuje nową ikonę (czasem trzeba odświeżyć z Ctrl+F5).

Podpowiedź

<img src="/img/logo.png" alt="Logo ZSMI" height="40" class="me-2">. Ikona musi być w formacie .ico albo zmień wpis w index.html.

ZAD 3Karta z plakatem z pól klasy★★☆

Zrób komponent karta-plakat z obrazkiem u góry karty, tytułem i przyciskiem „Szczegóły”. Adres obrazka, opis do alt i tytuł trzymaj w trzech polach klasy.

Kryterium sukcesu: zmiana pola z adresem w pliku .ts zmienia obrazek, a zmiana tytułu — napis; alt w narzędziach przeglądarki (Elements) ma wartość z pola.

Podpowiedź

[src], [alt] i {{ }} w tytule; obrazek z klasą card-img-top stoi przed card-body.

ZAD 4Galeria z podpisami★★☆

Zrób galerię z trzech zdjęć z podpisami. Każde zdjęcie umieść w znaczniku <figure> z podpisem <figcaption>. Podpisy i opisy alt mają się różnić: podpis jest dla wszystkich („Finał turnieju 2026”), alt opisuje, co widać na obrazku („Dwie osoby przy automacie do gier”).

Kryterium sukcesu: pod każdym zdjęciem jest podpis, zdjęcia mają zaokrąglone rogi, a każde alt opisuje treść obrazu.

Podpowiedź

Klasy Bootstrapa: figure, figure-img img-fluid rounded, figure-caption.

ZAD 5Polowanie na 404★★★

Wstaw na stronę pięć obrazków z adresami: /img/turniej.svg, img/turniej.svg, public/img/turniej.svg, /images/turniej.svg, /img/turniej. Zanim zapiszesz, przewidź w zeszycie, które się wczytają. Potem sprawdź w zakładce Network (filtr Img) status każdego z nich i zapisz tabelkę: adres → przewidywanie → status → wyjaśnienie.

Kryterium sukcesu: tabelka ma pięć wierszy z prawdziwymi statusami, a dla każdego obrazka, który się nie wczytał, umiesz wskazać przyczynę.

Podpowiedź

Adres bez ukośnika na początku liczony jest od <base href="/"> z index.html — sprawdź, co z tego wynika. Uwaga na adres bez rozszerzenia: serwer może odpowiedzieć statusem 200, ale zamiast obrazka odeśle stronę aplikacji — sprawdź kolumnę Type (document zamiast svg+xml).

ZAD 6Plakat zależny od kategorii★★★

Zrób kartę wydarzenia z polem kategoria, które przyjmuje jedną z wartości: 'turniej', 'roboty', 'druk3d'. Adres plakatu ma powstać z kategorii (/img/ + kategoria + .svg), a opis alt i tytuł — z metody tytul(), która dla każdej kategorii zwraca pełną nazwę wydarzenia. Dodatkowo dla kategorii 'roboty' karta ma mieć ciemne tło i biały tekst.

Kryterium sukcesu: zmiana jednego pola kategoria zmienia plakat, tytuł, alt i — dla robotów — kolory karty.

Podpowiedź

[src]="'/img/' + kategoria + '.svg'". Kolory: [class.text-bg-dark]="kategoria === 'roboty'" na elemencie card.

PODSUMOWANIE

Co trzeba zapamiętać

  • Pliki statyczne leżą w public, obok src; serwer podaje je bez kompilowania.
  • Adres zaczyna się od / i nie zawiera słowa public.
  • Adres z pola klasy przekazujesz przez [src]; da się go też skleić z kilku części.
  • Błędny adres nie zatrzymuje aplikacji — 404 widać tylko w narzędziach przeglądarki.
  • alt opisuje treść obrazu; ozdobnik dostaje alt="".
  • width i height rezerwują miejsce; img-fluid dopasowuje obrazek do kolumny.
  • W karcie obrazek z card-img-top stoi przed card-body.

Sprawdź się: plik leży w public/img/logo.png. Jaki adres wpiszesz w src i dlaczego nie ten z folderem public?

Dokumentacja: angular.dev — struktura projektu (folder public).

Postęp zapisuje się w tej przeglądarce.