CSS i Javascript

Ostatnia aktualizacja: 03 września 2020

Ze stylowaniem elementów możemy działać na kilka sposobów.

classList

Po pierwsze możemy utworzyć odpowiednie klasy, a następnie aplikować je dla danych elementów. Aby zarządzać klasami css danego elementu użyjemy właściwości classList(), która udostępnia nam kilka metod:

add("nazwa-klasy", "nazwa-klasy"*, "nazwa-klasy"...) dodawanie klasy lub kilku klas
remove("nazwa-klasy", "nazwa-klasy"*, "nazwa-klasy"*) usuwanie klasy lub kilku klas
toggle("nazwa-klasy") przełączanie (jak nie ma to dodaje, jak jest to usuwa) klasy
contains("nazwa-klasy") sprawdza czy element ma taką klasę
replace("stara-klasa", "nowa-klasa") zamienia starą klasę na nową klasę

el.classList.add("btn");
el.classList.add("btn", "btn-primary");
el.classList.remove("btn");
el.classList.toggle("btn");
el.classList.contains("btn");
el.classList.replace("btn", "element");

A dodatkowo jest tego jeszcze kilka. Wystarczy złapać dany element, wypisać go za pomocą console.dir, a następnie rozwinąć właściwość classList.

Mamy też drugą właściwość - className. Zwraca ona listę klas danego elementu w formie tekstowej. Możemy ją też wykorzystać do dodania wielu klas na raz:


element.className = "button button-big button-important";

style

Kolejnym sposobem dodawania styli jest użycie właściwości style. Dzięki niej możemy ustawić ale i odczytać style inline nadane dla danego elementu.


btn.style.backgroundColor = "#4BA2EA";
btn.style.fontSize = "1.6rem";
btn.style.borderRadius = "3rem";
btn.style.color = "#F7F781";

console.log("Kolor przycisku to: ", btn.style.backgroundColor);
console.log("Kolor tekstu to: ", btn.style.color);

Jeżeli właściwość składa się z jednego słowa, to zapisujemy ją tak jak w css. Jeżeli właściwość składa się z kilku słów oddzielonych myślnikiem, wtedy dla takiej właściwości musimy zastosować zapis camelCase. Możemy tutaj też zastosować zapis znany z obiektów:


el.style.fontSize = "1rem";
el.style["font-size"] = "1rem";

el.style.background = "linear-gradient(#fff, #ddd)";
el.style["background"] = "linear-gradient(#fff, #ddd)";

el.style.backgroundColor = "rgba(255,255,255,0.5)";
el.style["background-color"] = "rgba(255,255,255,0.5)";

Jak widzisz powyżej, za pomocą style możemy ustawiać wartości dla pojedynczych właściwości. Jeżeli chcielibyśmy ustawić kilka wartości na raz, możemy skorzystać z właściwości cssText lub ustawić je za pomocą setAttribute:


el.style.cssText = `
    color: red;
    background: blue;
    padding: 10px;
`;

el.setAttribute("style", "color: red; background: blue; padding: 10px;");

Pamiętaj tylko o tym, że powyższymi zbiorczymi metodami potencjalnie możesz nadpisać style, które wcześniej były dodane do danego elementu.

Staraj się też nie nadawać całych styli za pomocą powyższych właściwości. Stosuj je raczej tylko w przypadku, gdy dane style muszą być nadawane dynamicznie - np. gdy generujesz losowe tło dla elementu. Jeżeli jednak style są statyczne, o wiele lepszym rozwiązaniem będzie trzymanie ich w pliku css i dodawanie ich do elementu za pomocą classList. Dzięki temu oddzielasz warstwę wizualną od logicznej.

getComputedStyle()

Jeżeli ustawiamy style za pomocą powyższych sposobów, są one wstawiane inline w atrybucie style danego elementu.

style przycisku

Podobna zasada tyczy się odczytu. Jeżeli dany element nie ma ustawionych styli inline (wpisanych z palca, lub za pomocą JavaScript), to nie jesteśmy w stanie ich pobrać.


console.log(btn.style["font-size"]); //wypisze ""
console.log(btn.style.backgroundColor); //wypisze ""

//ustawiamy style inline
btn.style["font-size"] = "1.5rem";
btn.style.backgroundColor = "#4BA2EA";

console.log(btn.style["font-size"]); //wypisze "1.5rem"
console.log(btn.style.backgroundColor); //wypisze "#4BA2EA"

Bardzo często będziemy chcieli pobrać style, które są zadeklarowane w arkuszach stylów, a nie inline w kodzie HTML.

Żeby pobrać takie stylowanie musimy skorzystać z funkcji window.getComputedStyle(elem, pseudoEl*). Pierwszy parametr tej metody określa element, dla którego chcemy pobrać przeliczone style. Drugi - opcjonalny - pozwala pobierać style dla pseudo elementów (wtedy podajemy selektor jako np. "::before" lub "::after"):


const btn = document.querySelector(".button");
const style = getComputedStyle(btn);

console.log( style.height );
console.log( style["background-color"] );

Funkcja ta zwraca wartości w postaci jak widzi je przeglądarka. Przykładowo jeżeli my ustawimy kolor red, pobierzemy go w postaci rgb(255, 0, 0), jeżeli ustawimy wielkość w em, zwracana wartość będzie w px. Żeby dokładniej zobaczyć o co chodzi, przejdź do zakładki Elements w debugerze. Po prawej stronie będziesz miał zakładkę Computed.

Zakładka computed

Style pobrane za pomocą getComputedStyle() są tylko do odczytu. Próba zmiany ich wartości zakończy się błędem:

getComputedStyle error

setProperty() i getPropertyValue()

Obiekt style udostępnia nam też dodatkowe metody, wśród których znajdziemy:

el.style.setProperty(propertyName, value, priority*) służy do ustawiania stylowania. Ostatni opcjonalny parametr priority służy do ewentualnego dodania do danych styli deklaracji !important. Najczęściej jest pomijany.
el.style.getPropertyValue(property) służy do pobierania stylowania

el.style.setProperty("background-color", "#4BA2EA");
el.style.setProperty("font-size", "1.5rem");

el.style.getProperty("background-color");
el.style.getProperty("font-size");

Zastosowanie tych metod jak w powyższym kodzie jest raczej bez sensu, bo przecież właściwości takie możesz bez problemu ustawiać i pobierać za pomocą wcześniej pokazanej składni. Metody te mają jednak zastosowanie przy pracy z niektórymi składowymi CSS - szczególnie zmiennymi.


el.style.setProperty("--size", "1em");
el.style.getPropertyValue("--size"); //"1em"

Zmienne w CSS

CSS także doczekał się swoich zmiennych. Ich podstawowe użycie ma postać:


:root {
    --color : red; /* zmienne deklarujemy poprzedzając ich nazwę dwoma myślnikami */
}

.module-error {
    border:1px solid var(--color); /* a używamy z funkcją var() */
    box-shadow: 0 1px 3px var(--color);
}

.module-error-title {
    color: var(--color);
}

Zmienne w CSS zachowują się tak jak zmienne w JS - czyli ich zasięg jest dostępny dla coraz bardziej zagnieżdżonych elementów.

W powyższym kodzie zadeklarowałem zmienną --color w elemencie :root. Element taki dla stron napisanych w HTML jest równoznaczny z elementem html (można napisać tak i tak). Dzięki temu zmienna taka jest dostępna dla całego dokumentu. Zmienne możemy też deklarować w każdy elemencie z osobna. Dzięki temu dostępne są one tylko dla niego i jego dzieci:


.element {
    --color: red; /* zmienna dostępna tylko dla .element i jego dzieci */

    border: 2px solid var(--color);
    display: flex;
}

.element strong {
    border: 2px solid var(--color);
    color: var(--color);
    display: inline-block;
    padding: 5px;
}

.element::before {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: inline-block;
    background: var(--color);
}

.element:hover {
    --color: blue;
}
strong1 strong2

Zmienne CSS dają bardzo duże możliwości jeżeli chodzi o manipulację CSS, ponieważ za pomocą Javascript możemy dynamicznie zmieniać ich wartości - wystarczy tutaj wykorzystać metodę setProperty().


const elem = document.querySelector(".element");
elem.style.setProperty("--color", "black");

Przykład 1 - zmiana koloru

W pierwszym przykładzie za pomocą inputa typu color zmieniamy właściwości elementu:

Zmień kolor i najedź kursorem

<div class="element">
    Zmień kolor i najedź kursorem
</div>

<input type="color" class="color">

.element {
    --color : red;

    border: 2px solid var(--color);
    color: var(--color);
    padding: 30px;
    font-weight: bold;
    text-transform: uppercase;
    font-family: sans-serif;
    position: relative;
    background: #eee;
    transition: 0.5s;
}
.element:hover {
    background-color: var(--color);
    color: #fff;
}

const element = document.querySelector(".element");
const inputColor = document.querySelector(".color");

inputColor.addEventListener("change", e => {
    element.style.setProperty("--color", inputColor.value)
});

Podobna technika zastosowana jest na tej stronie jeżeli chodzi o tryb jasny i ciemny.

Przykład 2 - losowa pozycja


<button type="button" class="button-move">
    Zamknij reklamę
</button>

.button-move {
    --ml : 0px;

    padding:0.5rem 1rem;
    transform:  translate(var(--ml));
    transition: 0.3s;
}

const element = document.querySelector(".button-move");

setInterval(() => {
    element.style.setProperty("--ml", Math.random() * 300 + "px");
}, 300)

Przykład 3 - zmiana po najechaniu

W kolejnym przykładzie pobieramy pozycję kursora na elemencie i ustawiamy mu pozycję pseudoelementu z gradientem. Dodatkowo na hover zmieniamy jego wielkość:


<button type="button" class="button-test">
    <span>KLIK</span>
</button>

.button-test {
    --size: 0;
    --left: 0;
    --top: 0;

    border: 0;
    padding: 20px 70px;
    border-radius: 50px;
    text-transform: uppercase;
    font-family: sans-serif;
    color: #fff;
    overflow: hidden;
    position: relative;
    background-color: tomato;
}

.button-test span {
    position: relative;
    z-index: 1;
}

.button-test:hover { /* wielkość gradientu zwiększam na hover */
    --size: 400px;
}

.button-test:after {
    content: "";
    position: absolute;
    left: var(--left);
    top: var(--top);
    width: var(--size);
    height: var(--size);
    background: radial-gradient(circle closest-side, #4405f7, tomato 60%);
    background-repeat: no-repeat;
    transform: translate(-50%, -50%);
    transition: 0.3s width, 0.3s height;
    z-index: 0;
}

const element = document.querySelector(".button-test");

element.addEventListener("mousemove", e => {
    const rect = element.getBoundingClientRect();
    element.style.setProperty("--left", `${e.pageX - (rect.left + window.scrollX)}px`);
    element.style.setProperty("--top", `${e.pageY - (rect.top + window.scrollY)}px`);
})

Przykład 4 - zmiana pozycji elementów

Ostatni przykład możesz zobaczyć na oddzielnej stronie. To jeden z moich eksperymentów odnośnie animacji w CSS. Tutaj także wykorzystałem powyższe techniki do animowania elementów.

Trening czyni mistrza

Jeżeli chcesz sobie potrenować zdobytą wiedzę z tego działu, to zadania znajdują się w repozytorium pod adresem: https://github.com/kartofelek007/zadania-dom

W repozytorium jest branch "solutions". Tam znajdziesz przykładowe rozwiązania.

Wszelkie prawa zastrzeżone. Jeżeli chcesz używać jakiejś części tego kursu, skontaktuj się z autorem. Aha - i ta strona korzysta z ciasteczek.

Menu