Ostatnio otrzymałem ciekawe zadanie do wykonania. Miałem przystosować przycisk ładowania pliku na formularzu tak, aby w każdej przeglądarce wyglądał identycznie (albo chociaż podobnie względem siebie). Każdy, kto próbował to już kiedyś zrobić wie, że to niełatwe zadanie… A z wykorzystaniem samego arkusza styli praktycznie niewykonalne. Na wygląd kontrolek wpływ ma nie tylko używana przeglądarka internetowa, ale także system operacyjny, na której została ona otwarta.

Na pierwszy rzut oka widać, że wygląd jest raczej spójny pomiędzy przeglądarkami różnych producentów. Oczywiście sytuacja wygląda odmiennie w przypadku Internet Explorera i pole to wygląda zupełnie inaczej: przycisk umieszczony jest po drugiej stronie pola z nazwą pliku, a samo pole z nazwą posiada nieprzezroczyste tło oraz obramowanie, ale nie ma w nim napisu w przypadku braku pliku. Jak zatem upodobnić wygląd tej kontrolki do innych przeglądarek?

Szczęście w nieszczęściu kontrolka ta wraz z niestandardowym wyglądem otrzymała także dwie niestandardowe pseudoklasy. Klasy o których mowa to:

Powyższe pseudoklasy obsługiwane są wyłącznie przez wspomnianego wyżej Internet Explorera oraz przeglądarkę Edge. Jak zmienić zatem wygląd pola tekstowego? Tutaj sprawa jest prosta, podmieniamy atrybut background dla pola z nazwą pliku na kolor tła kontenera oraz zerujemy border:

input::-ms-value: { background-color: white; border: 0; }

Podmieniliśmy tło na odpowiedni kolor oraz usunęliśmy obramowanie, które zostało domyślnie dodane przez przeglądarkę. Jednak gdy nie załadujemy pliku, to pole tekstowe nadal jest puste, w przeciwieństwie do pozostałych przeglądarek. Niestety nic z tym nie zrobimy za pomocą samego CSS. Podobnie sytuacja wygląda z tekstem na przycisku.

Teraz pora na przesunięcie przycisku na prawą stronę. Nie zrobimy tego ani przy wykorzystaniu atrybutu float, ani za pomocą atrybutu display. Ale rozwiązać ten problem możemy za pomocą prostej, aczkolwiek ciekawej sztuczki:

input { -ms-transform: scaleX(-1); } input::-ms-value { background-color: white; border: 0; -ms-transform: scaleX(-1); } input::-ms-browse { -ms-transform: scaleX(-1); }

Najpierw całej kontrolce nadajemy atrybut transform: scaleX(-1), co powoduje odbicie lustrzane całego elementu w poziomie. Niestety teraz tekst na przycisku oraz w polu tekstowym też jest odbity w poziomie (odwrócony). Aby to zmienić, pojedynczym składowym kontrolki także nadajemy ten sam atrybut, przez co tekst na nich jest wyświetlany poprawnie (następuje odbicie lustrzane odbicia lustrzanego ;)). Dlaczego jednak dla całej kontrolki został wykorzystany atrybut transform z przedrostkiem -ms-? Zrobiłem tak dlatego, aby ta reguła była aplikowana wyłącznie w przypadku przeglądarki Microsoftu.

Tę sztuczkę można stosować praktycznie do wszystkich elementów, które możemy "chwycić" za pomocą selektorów CSS, nie tylko kontrolek formularzy. Zaletą tego rozwiązania jest bardzo dobre wsparcie przeglądarek, np. Internet Explorer obsługuje atrybut transform od wersji 9 (co prawda z przedrostkiem -ms-, ale obsługuje)… A z tą przeglądarką zazwyczaj jest najwięcej problemów.