EpicWEB.pl

webdesign, programowanie, phat lewt!

Ostatni projekt

ddrpl.com

Ostatnie wiadomości

[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:

CSS3!

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.

PHP - generowanie mapy witryny

Generowanie mapy witryny - prosta, wydawało by się - rzecz. Jednak, kiedy w naszej firmie pojawiło się wolne stanowisko programisty postanowiliśmy właśnie takie zadanie dać kandydatom do zrealizowania, w celu odsiania "programistów" od programistów.

Zadanie okazało się jednak wykraczające poza wszelkie normy i na jakieś 20 osób (na przestrzeni 5 miesięcy) udało się je zrobić 5. Z tego dwie skopiowały (nie do końca działające) rozwiązania z sieci...

Twoje zadanie - mając tabelę (CREATE TABLE `_tree` (`id` INT(11), `parent` INT(11), `sort` INT(11), `nazwa` VARCHAR(255))) napisz skrypt, który wygeneruje mapę witryny w HTML (w dowolnym standardzie). Większość osób zaczyna od napisania prostego zapytania wyciągającego wszystkie wpisy z parent = 0. Nieliczni dodadzą jeszcze sort. Później, jeżeli ktoś już to zrobi przystępuje do zagnieżdżania kolejnych poziomów while() a nam ręce opadają ...

Dlatego, drogi poszukiwaczu odpowiedzi w sieci, poniżej zamieszczam dwa rozwiązania - wykuj się ich na pamięć, przyjdź do nas i pewnie dostaniesz posadkę ...

Rozwiązanie 1 - rekurencja - dużo zapytań do SQL, mało myślenia:

function lev($parent) {
	$query = mysql_query('SELECT * FROM `_tree` WHERE `parent` = '.(int)$parent.' ORDER BY `sort` ASC');
	if(mysql_num_rows($query)) {
		echo '<ul>'."\n";
		while($dane = mysql_fetch_array($query, 1)) {
			echo '<li>'."\n";
			echo $dane['nazwa']."\n"; 
			lev($dane['id']);
			echo '</li>'."\n";
		}
		echo '</ul>'."\n";
	}
}

lev(0);

Rozwiązanie 2 - jedno zapytanie, nieco więcej myślenia:

function getData($parent) {
    $query = mysql_query('SELECT * FROM `_tree` WHERE `parent` >= '.(int)$parent.' ORDER BY `parent` ASC, `sort` ASC');
    $return = array();
    while($dane = mysql_fetch_array($query, 1)) {
        $return[] = $dane;
    }
    return $return;
}

function sortData($data, $root = 0, $level = 0) {
    static $return = array();
    foreach($data as $item) {
        if($item['parent'] == $root) {
            $item['level'] = $level;
            $return[] = $item;
            sortData($data, $item['id'], $level+1);
        }
    }
    return $return;    
}
foreach(sortData(getData(0)) as $item) {
    echo str_repeat('&nbsp;', $item['level'] * 5).$item['nazwa'].'<br />';
}

Niech mi ktoś powie, że to jest mega skomplikowane? Dzisiaj pojawił się jeden człowiek, który był po 2 kierunkach na Politechnice Łódzkiej. Po godzinie nic nie zrobił. Drugi - stwierdził, że pracował w Prado (taki framework) - więc zainstalował sobie WAMP na laptopie, zassał Prado i ... po 2 godzinach wyszedł bez "do widzenia".

Apple przewodnikiem Standardów Sieciowych*

* uwaga, nasze rozwiązania oparte na Otwartych Standardach Sieciowych wyświetlają się poprawnie tylko u posiadaczy przeglądarki Apple ® Safari oraz Mac OS X ® Snow Leopard ®

Tym krótkim wyjaśnieniem można podsumować prezentację rozwiązań wykonanych w HTML5, CSS3 i JS, które zastąpić mają Flasha w urządzeniach firmy Apple

Pierwsze, co rzuca się w oczy to to, że przedstawione prezentacje "nie działają" na niczym innym niż Safari. Nie ważne, czy wejdziecie przez stronę informacyjną, na docelowy adres etc. - standardy wg. Apple implementuje tylko Safari, więc nawet nie próbuj odpalać strony pod niczym innym.

Jest to pierwsze kłamstwo, ponieważ większość z zaprezentowanych rozwiązań obsługuje chociażby Firefox, a zdecydowaną większość da się obejrzeć w Chrome. No ale wiedziony hasłem marketingowym postanowiłem zainstalować Safari 4 i obejrzeć demonstracje.

Na pierwszy ogień poszło <VIDEO> które ... nie działa.

Wygląda na to, że Mozilla okłamała mnie twierdząc, że najnowszy Firefox dobrze radzi sobie z tagiem <VIDEO>. Okazuje się, że Standardy obsługuje tylko jeden kodek, w tylko jednym programie, tylko jednej Firmy. A przynajmniej tak twierdzi Tylko Jeden Steve. Nie wierzę mu. Przejdźmy do audio - niestety, nie mam kodeka MPEG-4. Wiadomo - mogę pobrać go ze strony Jednej Firmy. Jednego Steva.

Inne dema (czcionki, galeria, przejścia czy efekty w 2D) nie są praktycznie niczym nowym. Tak, transformacje 2D w CSS były już od jakiegoś czasu. Co ciekawe, Standardy w CSS wywoływane są za pomocą prefixów dla -webkit-* które działają tylko w przeglądarkach opartych na tym właśnie silniku. Skoro Safari jest w pełni zgodne ze standardami, a "inne nowe przeglądarki już niebawem zaimplementują te rozwiązania", to dlaczego muszę używać -webkit-border-radius i innych sztuczek, by wyświetlać odpowiednie efekty?

Ok, przejdźmy do najbardziej interesującej nas rzeczy - transformacje 3D. No, to wykonane dobrze mogło by rzeczywiście zabić Flasha, otworzyć developerom nowe możliwości (które klient będzie do oporu nadużywać) - zobaczmy -

No chyba ktoś tu sobie żarty ze mnie stroi? Serio? Żeby zobaczyć jak implementujecie coś, co wg. was jest Standardem potrzebuje kupić komputer, który produkuje tylko Jedna Firma, zainstalować na nim system, który wydaje tylko Jedna Firma oraz używać przeglądarki wydanej przez Jedną Firmę?

I to ma wg. was byś ten Otwarty Standard, który Safari już implementuje i który mogę już używać na stronach tak, by wzbogacić odczucia użytkowników? Nie, mi to raczej wygląda na rozwiązanie mające ułagodzić wzburzenie tych, którym brakuje Flasha. Pokazanie "hej, po co wam Flash! przecież to samo można zrobić w HTML5!" Można, tylko powiedzcie mi kto chce robić dwa rozwiązania - jedno - we Flashu, działające w 95% (wartość z kapelusza) przypadków - i drugie, wykonane w HTML specjalnie dla ludzi na oślep rzucających się na wszystko z logiem Apple?

Swoją drogą, jeżeli już inne nowe przeglądarki "dogonią" Safari we wspieraniu "standardów", to i tak nie będą się one de-facto nadawać do używania na co dzień do momentu aż nie będą one wspierane przez Internet Explorer, a każdy kto mówi inaczej albo ma grupę targetu zupełnie pozbawioną użytkowników IE, albo jest po prostu marzycielem.

Smokescreen - Flash bez ... pluginu

Smokescreen to nowy startup, który mylnie określany jest jako sposób na konwersję Flash do technologii, które wprowadza HTML5. Tak na prawdę, Smokescreen to plugin Flash napisany w JavaScript, który dodatkowo korzysta z technologii dostępnych w HTML5 np. tag ) jednak w większości korzysta on z dużo starszego rozwiązania - SVG.

Jak można się domyślić, powodem powstania pluginu Flash w wersji JS jest oczywiście brak wsparcia technologii Adobe na wielu platformach np. Apple iPad, które z kolei posiadają przeglądarki umożliwiające znośne wykonywanie kodu JS. Co prawda twórcom chodziło głównie o odtwarzanie reklam Flashowych na takich urządzeniach, co nie jest może najbardziej chwytliwym rozwiązaniem, ale jak widać udało się odpalić trochę bardziej skomplikowane flashe.

Jak dokładnie działa SmokeScreen? Jak już wspomniałem - nie jest to żaden konwerter, ale plugin, który powstał dzięki upublicznieniu specyfikacji. Plugin pozwala na uruchomienie aplikacji Flash wprost z pliku SWF i nie wymaga żadnej wcześniejszej modyfikacji. Niestety, jak to bywa z wersjami rozwojowymi (wersja 0.1.2 została opublikowana 27 maja 2010) bywa, plugin nie jest jeszcze w 100% kompatybilny i nie wszystkie Flashe udaje się w nim uruchomić.

Poniżej znajdziecie wideo-prezentację SmokeScreen na iPadzie:

Osobiście przyznam, że Smokescreen wydaje się ciekawym rozwiązaniem - ale chyba tylko dla posiadaczy produktów Apple i innych, nie posiadających oficjalnej wersji pluginu Flash. Należy pamiętać, że jest to implementacja w języku, który nie słynie z najlepszej wydajności - jednak może dzięki zastosowaniu JIT (WebKit zdaje się posiadać własny mechanizm kompilacji JS do kodu maszynowego) umożliwi on wyświetlanie wspomnianych reklam i mniej wymagających aplikacji Flash na urządzeniach mobilnych.

Aplikacja tworzona jest na zasadach Wolnego Oprogramowania i kod już niebawem powinien pojawić się na GitHub.com. Niecierpliwi mogą pobrać aktualną wersję prosto ze strony SmokeScreen.us