Niniejsza notka ma specyficzne przeznaczenie. Chociaż nie zdziwiłbym się, gdyby dla wielu osób okazała się interesująca i przydatna, to jej głównym celem jest przechowanie dla mnie pewnej wiedzy, której ogarnięcie zajęło mi całkiem sporo czasu. Tak, chodzi właśnie o tytułowy atrybut position
z CSS i jego działanie.
A zatem… Jak nazwa jednoznacznie sugeruje, atrybut ten ma dużo wspólnego z określaniem umiejscowienia elementu wyświetlanego dokumentu. Nie zawiera on jednak pozycji jako takiej, lecz sposób jej wyznaczania. Jest to więc atrybut wyliczeniowy, którego możliwe wartości są następujące:
static
– domyślny sposób pozycjonowania. Element zostanie umieszczony i będzie wyświetlany w miejscu, które wynika z położenia jego znacznika w źródle dokumentu, czyli w ciągu otaczającego go tekstu. (Jeśli oczywiście sam ten tekst nie został jakoś fikuśnie wypozycjonowany). Atrybuty określające współrzędne (left
, top
, itd.) są ignorowane.relative
– bardzo podobne do powyższego. Różnica polega na tym, że tutaj wspomniane atrybuty są wykorzystywane i mają wpływ na to, gdzie element jest wyświetlany. Ich punktem odniesienia jest “normalna” pozycja elementu w ciągu tekstu. Znanym przykładem są “wciskane” linki, polegające na przesunięciu łącza odrobinę w prawo i w dół, by dać wrażenie jego wciśnięcia:
To, czego position:relative
nie robi, to rzeczywista zmiana położenia elementu. Nawet jeśli jest on wyświetlany gdzie indziej, tekst będzie nadal łamany według jego normalnego położenia – tak samo jak przy position:static
.
absolute
– tzw. pozycjonowanie absolutne, które w rzeczywistości jest… względne. (Ah, ta logika webdesignu ;>). Przy tym ustawieniu element jest mianowicie wyjęty z normalnego ciągu tekstu, co czasem określa się jako stworzenie nowej warstwy
(layer). Jego pozycja jest wówczas określana (atrybutami left
itd.) względem elementu go zawierającego, którym to jest najbliższy element nadrzędny o pozycjonowaniu innym niż static
… Proste i nieskomplikowane, prawda? ;-)fixed
– stała pozycja. Stałość polega na tym, że element nie zmienia swojego położenia podczas przewijania strony, bo punktem odniesienia jest dla niego okno przeglądarki. Tak jak w przypadku absolute
, tutaj również tworzy on warstwę wyjęta z normalnego ciągu tekstu.Tyle teoria. W praktyce mamy kilka typowych przypadków użycia. Prawdopodobnie najbardziej skomplikowanym z nich jest zastosowanie position:absolute
ze względu na jego dziwne wymaganie odnośnie elementu zawierającego. Jeśli go nie uszanujemy, wówczas nasz ‘absolutnie’ wypozycjonowany element jako punkt odniesienia przyjmie cały obszar dokumentu, czyli element <body>
. Aby temu zapobiec, należy otaczającemu go pojemnikowi ustawić position
na relative
:
Wizualnie nic on się wtedy nie zmieni (jeśli sam nie zawiera atrybutów w stylu left
, itp.), natomiast będzie on mógł być kontenerem dla elementów z position:absolute
.
Komentarze umieszczamy w kodzie, aby opisać jego działanie. Są one przeznaczone wyłącznie dla osób czytających go i jedynie programy typu javadoc czy doxygen – służące automatycznemu generowaniu dokumentacji – mogą się niektórymi komentarzami interesować. Na pewno jednak nie robi tego kompilator.
Wymyślono jednak, że niektóre elementy kodu potrzebują innych, specyficznych “komentarzy”, przeznaczonych dla kompilatora właśnie. Różnie się one nazywają w różnych językach, ale ich głównym celem jest przekazanie dodatkowych informacji odnośnie klasy, metody, typu czy innego elementu programu, bez potrzeby stosowania.
W .NET takie dodatki nazywa się atrybutami i umieszcza przed wybraną deklaracją, w nawiasach kwadratowych (lub kątowych w przypadku Visual Basica), oddzielone przecinkami. Atrybuty te mogą dotyczyć właściwie wszystkiego, począwszy od wskazania na klasę, która może być serializowana (i pola, które nie powinny być) po informacje dla Form Designera na temat danej właściwości niestandardowego komponentu:
Ogólnie dotyczą one jednak różnych funkcji samej platformy .NET i służą wskazaniu, które elementy pełnią określone role w różnych rozwiązaniach, które działają w jej ramach. Można aczkolwiek definiować także własne atrybuty, a potem w czasie działania programu wydobywać o nich informacje przy pomocy mechanizmu refleksji.
A jak to wygląda w Javie? Otóż tam od wersji 1.5 istnieją adnotacje. Ich nazwy poprzedza się znakiem @
i umieszcza w osobnych linijkach, poprzedzających deklaracje, których dotyczą. Ponieważ tutaj język jest ściśle związany z platformą (maszyną wirtualną Javy), adnotacje czasami pełnią funkcje “brakujących” słów kluczowych lub dyrektyw dla kompilatora. Typowy przykład to adnotacja Override
:
którą możemy oznaczać przesłonięte wersje metod wirtualnych. Jest to praktyczne, gdyż w przypadku popełnienia błędu (np. literówki w nazwie) kompilator ostrzeże nas, że tak naprawdę zdefiniowaliśmy zupełnie nową metodę (bez tego błąd objawiłby się dopiero nieprawidłowym działaniem programu).
Naturalnie, możliwe jest też tworzenie własnych adnotacji oraz pobieranie informacji o nich przy pomocy refleksji. Aż korci, żeby sprawdzić, kto od kogo ściągał tutaj pomysły ;-)
W C++ deklaracje standardowo nie mają żadnych “ozdobników”, ale pod tym względem w różnych kompilatorach bywa różnie. Na przykład w Visual C++ mamy słówko __declspec
, które służy do całego mnóstwo różnych celów. Wśród nich są chociażby takie oto warianty:
__declspec(align(n))
służy do określania, jak dane (np. pola struktur) mają być wyrównane w pamięci. Dzięki temu będą one umieszczone tak, by zajmowały zawsze wielokrotność podanych n bajtów, co przy odpowiedniej wartości (np. 32) może zwiększyć wydajność lub (dla 1) zmniejszyć zajętość pamięci.__declspec(deprecated)
pozwala oznaczyć dany element kodu jako przestarzały. Jego użycie będzie skutkowało wtedy ostrzeżeniem kompilatora.__declspec(dllexport)
i __declspec(dllimport)
służą do tworzenia symboli eksportowanych w bibliotece DLL i do importowania tych symboli w innym programie.__declspec(property)
wprowadza konstrukcję właściwości do klasy, bardzo podobną do tych obecnych w Delphi. Po podaniu jednej lub dwóch metod dostępowych (do odczytu i ew. zapisu), otrzymujemy właściwość o danej nazwie i typie. Jaka szkoda, że to nieprzenośne :)Zasadniczo Visual C++ posiada też atrybuty podobne do .NETowych, które są konieczne do tworzenia interfejsów COM. Na szczęście nimi, jak i samym COM-em, nie trzeba już sobie zaprzątać głowy :)