[CSS] "Odznaki" w czystym CSS.
Wraz z tym jak co raz więcej przeglądarek zaczyna obsługiwać nowe kolejne wersje CSS możliwe jest stosowanie coraz to nowych technik, w celu osiągnięcia efektów, które do tej pory wymagały przemyślnych tricków HTML/CSS/JS albo stosowania grafiki.
Jednym z takich elementów są "odznaki", zwykle dodawane do produktu czy usługi w celu zakomunikowania klientowi, że są one godne jego uwagi - przykładowa odznaka wygląda tak:

Zwykle w celu zastosowania takiego rozwiązania przygotowuje się obrazek graficzny z gwiazdką, czy też innym kształtem i umieszcza go na stronie jako obrazek czy też tło znacznika HTML. Jeżeli mamy kilka rozmiarów lub kolorów - trudno, robimy albo kilka obrazków, albo - dla trochę bardziej zaawansowanych - używamy odwrotnego obrazku jako maski kadrującej tło.
Na szczęście z nadejściem wsparcia dla nowszego CSS możliwe stało się wstawienie takiego (oraz podobnych) elementów bez użycia grafiki. Na początek pokażę co chcemy osiągnąć:
CSS3!
Wygląda tak samo (prawie) jak wyżej? Super - Twoja przeglądarka wspiera "zaawansowane" właściwości CSS. Nie wygląda tak samo? Przestań używać IE. Niestety, nawet IE9 preview nie wspiera w tym momencie zastosowanych tu technik, więc musisz sam siebie zapytać, czy IE nie stanowi większości Twoich odbiorców. Nie? Świetnie - przystąpimy do sekcji elementu. Na pierwszy ogień HTML:
<span class="badge"><span><span>CSS3!</span></span></span>
Jak widać, nie ma obrazków - są za to 3 zagnieżdżone elementy - w tym wypadku span, ale jeżeli np. chcesz, by element był klikalny i dobry dla SEO nic nie stoi na przeszkodzie by zamienić kombinację na np.:
<a class="badge"><span><strong>OKAZJA!</strong></span></a>
Ok, HTML wydaje się prosty - zostaje nam zatem CSS:
.badge,
.badge span {
display: inline-block;
width: 40px;
height: 40px;
background: red;
color: white;
line-height: 40px;
text-align: center;
-moz-transform: rotate(30deg);
-webkit-transform: rotate(30deg);
-o-transform: rotate(30deg);
rotation: 30deg;
}
.badge {
-moz-transform: rotate(300deg);
-webkit-transform: rotate(300deg);
-o-transform: rotate(300deg);
rotation: 300deg;
}
Ok, bez paniki - tak na prawdę jest to prostsze niż wygląda. Większość właściwości znamy już z poprzednich wersji CSS. display: inline-block oczywiście nakazuje traktowanie obiektu jako element blokowy, jednak pozostaje on w linii z tekstem, width i height określają szerokość i wysokość naszej odznaki. Dochodzi za to jedna nowa własność - rotation (zapisy -*-transform: rotate przeznaczone są dla konkretnych przeglądarek, samo rotation jest proponowane w standardzie CSS i niejako zapewnia nam kompatybilność, kiedy już właściwość ta będzie w pełni obsługiwana).
Co mówi nam ta właściwość? Prosto się domyśleć - nakazuje, by przeglądarka po wyrenderowaniu elementu obróciła go o podaną wartość wyrażoną w stopniach wg. jego środka. Jak widać przy 3 elementach suma obrotów sprowadza się do 360°, tak, by napis był w odpowiedniej postaci. De-facto nasza gwiazdka składa się z 3 nałożonych na siebie elementów:
CSS3!
Oczywiście odpowiednio modyfikujące (dodając kolejne span) kod HTML oraz CSS (zmniejszając kąt oraz dobierając width/height) możemy zwiększyć ilość ramion naszej gwiazdy. A Ci, którzy wolą kwiatki, mogą zastosować jeszcze border-radius:
CSS3!
Oczywiście zdaję sobie sprawę, że póki IE nie zacznie obsługiwać poprawnie CSS nie ma co marzyć o stosowaniu takich technik w komercyjnych rozwiązaniach, ale samorozwój jest zawsze pożądany ;)
Aktualizacja
Wasacz, w komentarzu wypomina mi, że efekt ten można stworzyć także w CSS z wykorzystaniem selektora :after: oraz :before - i rzeczywiście jest taka możliwość:
CSS3!
By osiągnąć taki efekt musimy użyć nieco bardziej zawiłego CSS:
.badgeSt:after,
.badgeSt:before,
.badgeSt {
display: inline-block;
width: 40px;
height: 40px;
background: red;
color: white;
line-height: 40px;
text-align: center;
position: relative;
}
.badgeSt:after
.badgeSt:before {
z-index: -1;
content: "";
position: absolute;
top: 0;
left: 0;
}
.badgeSt:after {
-moz-transform: rotate(30deg);
-webkit-transform: rotate(30deg);
-o-transform: rotate(30deg);
rotation: 30deg;
}
.badgeSt:before {
-moz-transform: rotate(-30deg);
-webkit-transform: rotate(-30deg);
-o-transform: rotate(-30deg);
rotation: -30deg;
}
Pojawiają się dwa nowe zagadnienia - wspomniane :after, :before oraz właściwość content. Selektory pozwalają nam na stworzenie i ostylowanie elementu HTML który zostanie umieszczony (odpowiednio) za oraz przed zawartością wskazanego elementu - tak jakby został on na sztywno wpisany do znacznika. Nowo utworzony element nie jest jednak żadnym znacznikiem (nie jest to ani span, ani stron etc.) więc by został wyświetlony musimy wstawić do niego jakąś zawartość - chociażby pusty łańcuch znaków - tu właśnie wkracza kolejna nowość czyli content. Parametr ten pozwala nam na określenie zawartości znacznika za pomocą CSS (więcej w specyfikacji). Dla poprawy wyświetlania musimy jeszcze zastosować z-index tak, by nasz tekst był na wierzchu.
Komentarze
Komentarz użytkownika Wasacz
26 06 2010Inspirowane blogiem peceta? ;-)
Świetny pomysł, można by w sumie pokombinować z GC, bo jest ::before i ::after do wzięcia, wtedy by można się tych spanów pozbyć.
I trochę mi zepsułeś Internet w Operze, nie domknąłeś znacznika – to chyba przez to.
Komentarz użytkownika BTM
26 06 2010Nie, nie Pecetem, akurat jakoś tak się zgraliśmy ;-)
::before i ::after można w sumie wykorzystać - nie przyglądałem się, nie wiem jak z wydajnością tego (czy CSS nie jest renderowany od zera przy każdym napotkaniu ::before i ::after? bo przecież :nth-child się może zmienić).
Poprawiłem HTML (jednego span nie zamknąłem) - powinno być ok.
Komentarz użytkownika Wasacz
26 06 2010Ale dlaczego miałby być renderowany od zera? Wydajność, to może być kiepska, gdy naużywasz na przykład box-shadow.
Komentarz użytkownika pecet
26 06 2010Mam powiększonego fonta i już tekst się wylewa z tej twojej odznaki, trochę bez sensu.
Komentarz użytkownika BTM
26 06 2010Ktoś jeszcze używa text-only zoom? Ok, jutro popatrzę czy coś zmieni przerobienie z px na em - powinno być ładniej.
Komentarz użytkownika Wasacz
26 06 2010BTM, nie zmieni. Ten firefoksowy jest powiększany bez względu na CSS.
Komentarz użytkownika SpeX
26 06 2010Jeden CSS do obu wersji HTML?
Komentarz użytkownika BTM
26 06 2010Nie, do drugiej już CSS nie wklejałem w przykładzie - możesz go podejrzeć w źródle stylów: http://anfo.pl/blog/examples.css
Komentarz użytkownika css3.pl
27 06 2010Dziwne, że jak na Twitterze pojawia się link do jakiegoś tutorialu, to zaraz znajduje się kilka osób, które wpadły na identyczny pomysł! Ale tak samo jak w przypadku oryginału, tutaj przykład również jest nie najwyższych lotów, ponieważ w znaczniku 'a' są użyte 'span' i 'strong', a można to zrobić na samym znaczniku 'a', tak jak pisał @Wasacz.
Poza tym w obecnej formie (czyli z nadmiarowym kodem) stosując filtry, pierwszy przykład zadziała również w IE.
Komentarz użytkownika BTM
27 06 2010@css3.pl: gdzie na Twitterze? Wysłali wszystkim użytkownikom prywatne wiadomości? Sam Twitter gdzieś zastosował? Sorry, nikt z obserwowanych przeze mnie osób nie opisywał takiego rozwiązania.
Wiem, że stosując filtry da się zrobić to w IE (z użyciem macierzy przesunięcia, pisałem o tym tutaj: http://anfo.pl/css-transform/).
Komentarz użytkownika Basti
27 06 2010Wkradł Ci się do tekstu błąd:
"zmniejszając kont" -> "zmniejszając kąt"
Komentarz użytkownika BTM
27 06 2010Dzięki, poprawione.
Komentarz użytkownika BTM
27 06 2010@Wasacz: a tak z Ciekawości - jak by można to było zrobić używając :before i :after? Bo content nie pozwala na wstawianie tagów z tego co widzę (http://www.w3.org/TR/CSS2/generate.html#content)
Komentarz użytkownika Wasacz
27 06 2010Proszę: http://stuff.wasacz.net/xhtml/css3-badge/
Komentarz użytkownika BTM
27 06 2010Dziękować :)
Komentarz użytkownika Wasacz
27 06 2010A tak w ogóle, to Opera nie obraca outline ;-)
Komentarz użytkownika Szymon
27 06 2010@BTM "Ktoś jeszcze używa text-only zoom?" niektóre przeglądarki używają, pod conkeror Twój przykład się brzydko skaluje (tekst wyjeżdża z kleksa przy powiększaniu).
Komentarz użytkownika Africarpa
28 06 2010Napisz jakie jeszcze ulepszenia wprowadzili w CSS3? Akurat dla odznaki nie widzę zastosowania, ale przetestuję to.
Komentarz użytkownika css3
28 06 2010@BTM - przykład który miałem na myśli. http://matthewjamestaylor.com/blog/css3-starbursts
Zastosowanie ::after i ::before wydaje się oczywiste, dlatego Twój artykuł i tamtego autora, są tak podobne, ale oczywiście nie twierdze, że go czytałeś.
Komentarz użytkownika BTM
28 06 2010Pierwsze widzę - raczej nie subskrybuję przez Twittera zbyt dużo frontendowców - chyba, że Polskich ;-) Ostatnio musiałem dorobić takie odznaki do jednego z naszych sklepów (oczywiście jako obrazki, IE jednak wciąż króluje) więc to tak trochę wylewanie żalów.
Komentarz użytkownika css3.pl
28 06 2010Zgadzam się, na razie te wszystkie nowości to sztuka dla sztuki, w produkcji raczej nie do zastosowania. Można przewidywać, że IE6 wkrótce (rok, dwa) zniknie całkowicie, ale co z IE7 i IE8? Najczarniejszy scenariusz, to że będą się trzymać tak długo, jak systemy operacyjne do których są przypisane.
Komentarz użytkownika BTM
28 06 2010Zależy o jakich dokładnie nowościach mówimy. Ja już normalnie w komercyjnych aplikacjach stosuję np. border-radius, które nie działają na IE, ale też nie są aż tak kluczowe, by przez nie blokować cała realizację.
Wydaje mi się, że IE7 i IE8 będzie dużo łatwiejsze do wyparcia niż IE6 - aktualnie trzymanego z uwagi na wsparcie dla starych aplikacji intranetowych oraz z czystymi instalacjami XP. Windows 7 i Windows Vista już ładnie uparcie przypominają o aktualizacji do najnowszej wersji.
Komentarz użytkownika css3.pl
28 06 2010Windows XP posiada obecnie ponad 68% rynku systemów operacyjnych (według ranking.pl), a przecież Vista jest od dawna, Windows 7 to nowość, ale ludzie nie rzucają się na niego jak na świeże bułeczki - szczególnie firmy o których wspomniałeś - z przesiadką trochę poczekają, bo to zawsze wiąże się z kosztami.
Zgodzę się, że CSS3 i HTML5 można stosować wybiórczo, ale to jest taki przedsmak tego, co nas czeka, jeśli znikną stare wersje IE - właściwie stare i obecna, bo IE9 jeszcze nie ma i nie wiadomo kiedy będzie. Chyba, że Microsoft zrobi jakiś radykalny krok, w celu zmuszenia użytkowników do porzucenia starych wersji na korzyść jednej, najnowszej. Jednak nie spodziewałbym tego z ich strony. Microsoft podkreślał wiele razy, że dotrzyma obietnic i będzie wspierał stare systemy, oraz aplikacje tak długo, jak się zobowiązał, bo tego oczekują od nich klienci. I widać to na przykładzie IE6, nawołują do jego porzucenia, ale na gadaniu się kończy, to użytkownik decyduje.
Komentarz użytkownika BTM
28 06 2010Tak, tylko że XP i tym samym IE6 w końcu przestanie być wspieranym i korporacje chcąc, nie chcąc będą musiały zaktualizować systemy. Poza tym intranety wciąż są aktualizowane i już raczej nie wykorzystuje się technik rodem z IE6 (ActiveX np.).
Poza tym zważ na zwiększenie dynamiki zakupów nowego sprzętu wraz ze spadającą ceną - a każdy nowy komputer / laptop to Windows Vista albo Windows 7 (nie mówimy tu o innych OSach). Vista może jest od dawna, ale fala fanbojów Linuxa i innych osób, które krytykowały ją nie mając z nią stycznością za czasów braku SP spowodowała swoje.
Zmiana z IE8 na IE9 będzie na pewno (wciąż, moim zdaniem) dużo łatwiejsza niż z IE6 na IE7 - wystarczy popatrzeć na rozkład procentowy na przestrzeni dziejów.
No i wprowadzenie ekranu wyboru przeglądarki też powinno wpłynąć pozytywnie na popularność innych niż IE przeglądarek. W jakimś śmiesznym stopniu :-)
Komentarz użytkownika css3.pl
29 06 2010Sam IE6 nie rozwiązuje sprawy, bo IE7 jest niewiele lepszy, nawet IE8 nas nie urządza, bo mocno odstaje od tego co już dzisiaj prezentują przeglądarki internetowe, a one się wciąż rozwijają, IE8 nie.
MS będzie wspierał system Windows XP do 8 kwietnia 2014. IE6 zniknie, chociaż ja myślę, że u nas zniknie już za 2 lata, bo jest tendencja spadkowa, która temu wróży. Potem nie wiadomo co dalej, bo w najnowszym Windows 7 mamy przecież IE8, możemy mieć powtórkę z rozrywki. Co z tego, że będzie wersja IE11, jeśli ludzie będą mieli Windows 7 w którym startowo jest IE8?
Jedynym rozsądnym wyjściem wydaje się nie umieszczanie przeglądarki w systemie operacyjnym, tylko pobierać ją z internetu w momencie pierwszego połączenia. Czyli otwiera nam się okno wyboru przeglądarki, wybieramy przeglądarkę, dopiero teraz instaluje się w systemie i mamy najnowszą wersję. Obecnie jest tak, że ludzie instalują system na nowo i nie pobierają serwis paków, ani aktualizacji, bo to długo się ściąga - takie tłumaczenia słyszałem.
Mam jednak nadzieję, że tak źle nie będzie.
Komentarz użytkownika BTM
29 06 2010IE8 nas nie urządza, bo mocno odstaje od tego co już dzisiaj prezentują przeglądarki internetowe, a one się wciąż rozwijają, IE8 nie.
No jak nie? Przecież trwają intensywne prace nad IE9 - nie spodziewaj się, że MS wypuści łatkę do IE8 dodającą obsługę nowych rzeczy w CSS czy też HTML.
Nie zakładam powtórki z rozrywki, ponieważ świadomość konsumenta została znacznie poprawiona - dodatkowo, duża część tych IE6 to programy korporacyjne, w których pracownicy muszą korzystać z akurat tej wersji przeglądarki z uwagi na stare oprogramowanie. Nowe aplikacje nie są już obwarowane takimi koniecznościami więc przejście z IE8 na IE9 będzie dużo szybsze niż z IE6 na IE7. Jestem w stanie postawić na to miesięczną pensję ;-)
Jedynym rozsądnym wyjściem wydaje się nie umieszczanie przeglądarki w systemie operacyjnym, tylko pobierać ją z internetu w momencie pierwszego połączenia.
Nie jest to rozwiązanie wszelkich problemów, bo:
- większość użytkowników, których korzystanie z internetu kończy się na graniu na Kurnik.pl (halo Mamo ;)) pobierze IE bo ikonka kojarzy im się z internetem i to już znają (ok, moja mama używa Firefoxa bo jej kazałem :>)
- w korpo systemy są instalowane bez nadzoru - czy ktoś orientuje się , czy przy takiej instalacji również można wybrać przeglądarkę?
Komentarz użytkownika css3.pl
30 06 2010Albo Cię nie zrozumiałem albo coś pokręciłeś. Co z tego, że trwają prace nad IE9? To bardzo, dobrze ciesze się z tego, ale to nie zmienia faktu, że jeśli ktoś będzie chciał korzystać z IE7 lub IE8, to będzie z niego korzystał, nawet przez kolejnych kilka lat. Analogicznie, jak dziś korzystają z IE7 - mogą aktualizować do IE8, ale tego nie robią. To nazywam powtórką z rozrywki.
To, że z IE6 korzystają głównie korporacje, to może być mit. To znaczy - nie neguje tego, ale nie widziałem żadnych danych ani statystyk, które mogłoby potwierdzić, że ma to znaczący wpływ, jaki to procent, tego nie wiemy. Przejście z IE8 do IE9 na pewno będzie szybsze, niż z IE6 do IE7. Chociażby dlatego, że IE6 czekał na swojego następcę aż 5 lat, IE8 ma dopiero roczek, a już szykuje mu się braciszek.
To nie jest problem tylko Internet Explorera. Firefox też ma kilka wersji, teraz to nie robi dużej różnicy, bo CSS3 i HTML5 stosujemy wybiórczo, ale w przyszłości może to być problem, bo okaże się, że jakiś tam procent użytkowników korzysta ze starych wersji Firefoksa. Statystyki, np. rankig.pl podają, że obecnie ponad 12% użytkowników korzystających z Firefoksa, ma wersję 3.0, a ten ma już skończone 2 lata! To jest ponad 4% użytkowników w internecie. Na co czekają ci ludzie? To też wina korporacji, albo ciemnogród?
PS: ale się oftopik zrobił.
Komentarz użytkownika BTM
30 06 2010Zacznę od końca ;-)
To też wina korporacji, albo ciemnogród?
W tym wypadku - tego drugiego. Założę się, że większość tych ludzi to mamy, dziadkowie, którym syn zainstalował Firefoxa kiedyś-tam i od tego czasu komputer nie jest aktualizowany. Firefox sam z siebie proponuje aktualizację z wersji 3.6.x do 3.6.y, ale z tego co pamiętam, z 3.0 do 3.x już nie proponował i trzeba się było samemu zatroszczyć.
Myślę, że do przyśpieszonego przejścia na nowe wersje przeglądarek przyczyni się rozwój aplikacji internetowych i akcje wielkich portali typu YouTube które promują nowe wersje przeglądarek (w tym wypadku jest to wyparcie IE6, ale kto wie czy z czasem nie będzie to wyparcie IE7 etc.)
Ja zdaje sobie sprawę, że do czasu aż przeglądarki wspierające CSS3 zdominują rynek, to ja już pewnie będę na emeryturze - to takie pobożne życzenia :)
Komentarz użytkownika Łukasz
30 06 2010Jedno mnie w tym przykładzie zastanawia... Przecież nie używa się tych "gwiazdek" tylko w jednym kolorze ;) Zawsze jest to przynajmniej jakiś gradient. Można użyć opcji gradientu dla gecko i webkit, jednak presto i trident przy tym sobie nie poradzą. Poza tym wątpię, aby wyglądało to jednolicie przy zastosowaniu transform.
Komentarz użytkownika BTM
30 06 2010Można - możesz dodać sobie klasę blue czy jaką tam uważasz i niech ona zmienia tylko i wyłącznie kolor obiektu.
Komentarz użytkownika Łukasz
30 06 2010Tylko że dla każdego obiektu ułożenie gradientu musiałoby być inne, aby uzyskać jednolity kolor na całym obszarze gwiazdki. A to oznacza dodatkowy tekstu w css... Czyli w chwili obecnej ni jak ma się to do, dobrze skompresowanego obrazka (svg też).