Poprawna odpowiedź to JavaScript, bo właśnie ten język działa bezpośrednio w przeglądarce użytkownika i pozwala na dynamiczną weryfikację formularzy jeszcze przed wysłaniem danych na serwer. JavaScript ma dostęp do drzewa DOM, więc może odczytać wartości pól, sprawdzić, czy nie są puste, czy e‑mail ma poprawny format, czy hasło ma odpowiednią długość, a nawet czy dwa pola hasła są identyczne. Z mojego doświadczenia to jest absolutny standard w nowoczesnych aplikacjach webowych: najpierw lekka walidacja po stronie klienta w JS, a dopiero potem solidna walidacja po stronie serwera. Dobrym przykładem jest formularz rejestracji: po wpisaniu zbyt krótkiego hasła JavaScript może od razu wyświetlić komunikat pod polem, bez przeładowania strony. Można też blokować przycisk „Wyślij”, dopóki wszystkie wymagane pola nie są poprawnie wypełnione. W praktyce często używa się zdarzeń takich jak onsubmit na formularzu albo input/blur na polach, żeby na bieżąco sprawdzać dane. Można też korzystać z gotowych bibliotek walidacyjnych, ale pod spodem i tak pracuje JavaScript. W dobrych praktykach przyjmuje się zasadę: walidacja po stronie klienta poprawia wygodę i szybkość obsługi (user experience), ale nie zastępuje walidacji po stronie serwera. JavaScript służy więc do „pierwszej linii obrony” i podpowiedzi użytkownikowi, a serwer (np. w PHP czy innym języku backendowym) musi i tak wszystko jeszcze raz sprawdzić ze względów bezpieczeństwa. Warto też pamiętać o wykorzystaniu wbudowanych mechanizmów HTML5 (atrybuty required, type="email" itd.), ale to JavaScript daje pełną kontrolę nad logiką i komunikatami błędów, bo pozwala tworzyć własne reguły i reagować na konkretne zachowania użytkownika.
W tym pytaniu łatwo się pomylić, bo wszystkie wymienione technologie występują w kontekście stron WWW, ale pełnią zupełnie różne role. Weryfikacja kompletności formularza „po stronie przeglądarki” oznacza, że logika musi działać u użytkownika, w jego browserze, zanim dane trafią na serwer. I tu kluczowe jest rozróżnienie: co działa po stronie klienta, a co po stronie serwera. CSS służy wyłącznie do opisu wyglądu – kolory, marginesy, rozmiary czcionek, układ elementów. Nie ma dostępu do wartości pól formularza w sensie logicznym. Można co najwyżej zmieniać styl w zależności od pseudo-klas (np. :valid, :invalid w HTML5), ale to są wbudowane mechanizmy przeglądarki, a nie „logika programu” w CSS. CSS nie umożliwia napisania warunku typu: jeśli pole A i pole B są puste, to pokaż taki komunikat i zablokuj wysłanie formularza. PHP z kolei jest językiem typowo serwerowym. Kod PHP wykonuje się na serwerze, po wysłaniu formularza, a nie w przeglądarce. To świetne narzędzie do walidacji danych po stronie serwera, zapisania ich do bazy, obsługi sesji i całej logiki backendowej, ale nie zrealizuje walidacji „na żywo” w momencie, gdy użytkownik dopiero wypełnia formularz. Typowym błędem myślowym jest założenie, że skoro PHP często pracuje z formularzami, to „sprawdza formularz”. Owszem, ale dopiero po jego wysłaniu. Ruby on Rails to natomiast framework backendowy napisany w Ruby, również działający na serwerze. On także ma bogate mechanizmy walidacji modeli i danych, ale znowu – wszystko dzieje się po stronie serwera. Framework może generować formularze, przyjmować dane, walidować je i zwracać błędy, ale przeglądarka sama z siebie nie uruchamia kodu Railsów. Jeżeli w treści pytania pojawia się wyraźny zapis „po stronie przeglądarki”, to praktycznie zawsze chodzi o technologię kliencką, czyli JavaScript lub ewentualnie rozwiązania na nim oparte (np. frameworki front-endowe). Warto o tym pamiętać, bo rozróżnienie klient–serwer to jedna z podstaw w programowaniu webowym i często decyduje o poprawności odpowiedzi w takich zadaniach.