Mam pomysł na cykl artykułów, idealny pod moją obietnicę złożoną jakiś czas temu. Obiecałem sobie i Wam, że zajmę się bardziej regularnym pisaniem notek na blogu, tak by zaczął w końcu żyć. I choć ciężko u mnie ze znalezieniem czasu to nie dam się! Oto pierwszy artykuł z cyklu "Pseudoklasy i pseudoselektory CSS". Zapoznajmy się z targetowaniem.

Słowem wstępu powiem Wam szczerze, że zastanawiałem się o czym pisać- tematów jest wiele, całe mnóstwo. Front-end (tak, Piotrek "Piecioshka" Kowalski swoim artem przekonał mnie o poprawności tego zwrotu i zamierzam od dziś pisac poprawnie. Mało tego- jak tylko znajdę chwilkę weny to na szybko przerabię wszelkie "frontendy" na "front-endy"- grunt to udoskonalanie siebie i swoich projektów, nawet o tak małe rzeczy) i jego możliwości są tak olbrzymie w swoim potencjale, że można by zebrać setkę front-end developer’ów, a każdy mógłby codziennie pisać po 5 notek i przez rok by tematy im się nie wyczerpały… Ponadto znacznie lepsi ode mnie świetnie wszystko opisują tak dogłębnie analizując dany temat, że stanowią dla mnie inspirację… Ale każdy znajdzie swoją niszę ;) Artykuły z tego cyklu będą przeznaczone bardziej dla początkujących, ale może i Ci bardziej doświadczeni coś ciekwego wyhaczą.

Mój cykl artykułów będzie dotyczył pseudoklas i pseudoselektorów, które są bardzo przydatne, o ile ktoś nam pokaże do czego tego użyć. Postaram się też zawsze dodać jakąś ciekawostkę lub metodę na wykorzystanie ich do czegoś przydatnego.

Przejdźmy już do właściwej treści. Wyobraźmy sobie stronę, na której posiadamy szereg zakotwiczonych linków, które po kliknięciu przenoszą nas na pewien fragment strony. Robi się to prosto:

<a href="#id-targetu">link</a>

następnie elementowi, który ma być celem tego linku przypisujemy identyfikator id-targetu. Spoko, to jest proste i pewnie niejeden z Was coś takiego robił. Jednak co w przypadku, gdy tworzymy stronę, gdzie mamy artykuł z wieloma odnośnikami do źródeł zewnętrznych i gdy chcemy pod artykułem stworzyć bibliografię? Gdy kliknę odnośnik numer 1 przejdę tylko na pozycję tego elementu, ale jeśli będzie tam cały tłumek...

Jednak co byście powiedzieli na to, że gdy kliknę odnośnik do takiego źródła na stronie to w tej stopce z bibliografią dana pozycja nam się podświetla wskazując "hej, to o mnie chciałeś poczytać!"

Taka sytuacja jest np. na Wikipedii, gdzie źródła są na dole strony.

Samo działanie opiera się o pseudoselektor :target. Sprawa jest dość prosta gdyż piszemy przykładowo:

:target{background:#f0c}

by nasz element docelowy po kliknięciu posiadał tło różowe. Ba, jeśli przejdziemy na stronę z już dopisanym odpowiednim hashem (czyli np. www.test.pl/index.html#element-2) to od razu będzie on podświetlony. Dodatkowo całkiem fajna sprawa, gdyż takiemu elementowi możemy przypisać nie tylko tło czy kolor, ale także wszelkie inne właściwości jak wielkość fontu, border, transformacje 2D czy 3D.

Dodatkowo możemy zdefiniować różne zachowanie dla różnych elementów. Przykładowo:

:target {
	background: #536b9c;
}

div:target {
	font-size: 50px;
	line-height: 50px
}

.test:target {
	color: #fff
}

Innymi słowy- każdy ztargetowany element ma niebieskie tło, jeśli jest div'em to na dodatek font mu się zmieni, a jeśli przy tym ma klasę o nazwie "test" to dostanie w gratisie jeszcze biały kolor tekstu.

Tak wygląda to w praktyce:
http://poligon.kamilrogala.it/cykle/pseudoselektory-css/target/css/

Jednak co ze wsparciem przeglądarek? Jest spoko, nie musicie się obawiać o nic- jedyny hipster w tym gronie to IE8 i jego starsi bracia, o ile CanIUse.com się nie myli to obecnie IE8 używa 0,34% Internautów.

Jeśli ktoś jednak chce trochę "hipsteriady" to są alternatywy w postaci niezastąpionego JS!

//zaciągam wszystkie linki z danego kontenera
var menuLinks = document.querySelectorAll('.menu a');
// menuLinks zwracany jest jako tzw. nodelist, który potraktować można pętlą
// tworzymy kolejne event listenery dla kliknięcia w poszczególną pozycję menu
for (var i = 0; i < menuLinks.length; i++) {
	menuLinks[i].addEventListener("click",
	function () {
		//pobieramy atrybut href z konkretnego linka
		//nastepnie z wyniku kasujemy znak #
		//wynik tej operacji z kolei jest parametrem metody getElementById
		//zaznaczony element jest zapisywany do zmiennej targetobject
		targetObject = document.getElementById(
			this.getAttribute('href').replace('#', '')
		);
		//poszukujemy ewentualnie juz podświetlonego elementu
		oldTarget = document.querySelector('.js-highlighted');
		if (oldTarget !== null) {
			//jeśli go wykryjemy- kasujemy z jego spisu klas klasę podświetlającą
			oldTarget.classList.remove('js-highlighted');
		}
		//dla wybranego elementu dodajemy klasę podświetlenia
		targetObject.className += 'js-highlighted';
	},
	false);
}

Całość wygląda na żywo tak:
http://poligon.kamilrogala.it/cykle/pseudoselektory-css/target/js/

Skrypt pełny nie jest, bo i sama notkę pisze w biegu między kolejnymi zajęciami- brakuje mu wykrywania hasha w adresie URL, gdyz podświetlanie następuje tylko po kliknięciu.

Jednak w obu wypadkach czegoś mi mało… już wiem- stronka nieładnie przeskakuje- klikam i w ciągu milisekundy jestem gdzieś na dole strony! Co gdyby płynnie zjeżdżało?

Wykorzystajmy proste, popularne i lubiane jQuery.

//tworzę metodę dla wszystkich linków w danym kontenerze
$('.menu a').click(function (e) {
	//przechwytuję i zatrzymuję domyślne działanie klikniętego elementu
	//dzięki temu link po kliknięciu nie przejdzie do swojego href'a
	e.preventDefault();
	//pobieram do zmiennej target atrybut href- będzie to mój element docelowego
	target = $(this).attr('href');
	//pobieram pozycję od góry strony dla elementu docelowego
	targetOffset = $(target).offset().top;
	//każdy element nie będący elementem docelowym traci klase podświetlającą
	$('*').not(target).removeClass('jquery-higlighted');
	//do targetu dodajemy klasę podświetlającą
	$(target).addClass('jquery-higlighted');
	//na koniec dodajemy płynne przejscie do pozycji elementu docelowego
	$('html,body').animate({
		scrollTop: targetOffset
	}, 800);
});

No i wszystko bajlando
http://poligon.kamilrogala.it/cykle/pseudoselektory-css/target/jquery/

Ten skrypt jest podobnie jak poprzedni niedopracowany- brakuje odświeżenia URL'a oraz podświetlania po załadowaniu strony, ale hej! pisałem dłużej tą notkę niż ten skrypt ;) to będzie fajny temat na jakiś inny artykuł.

Jak widzicie- prosta rzecz, która ma duży potencjał i którą można wykorzystać do wielu rzeczy. Przykładowo możemy stworzyć system tabów, utworzyć prosty modal, albo wyobraźcie sobie animacje CSS danego elementu po kliknięciu linka- niektóre rzeczy mogą się w niektórych wypadkach ograniczyć tylko do CSS, bez używania JS.

Kto wie co przyniesie przyszłość i czy (oraz ewentualnie jak) będzie rozwijany ten pseudoselektor?