Na koniec spójrzmy na źródło problemu
Pola wyboru są renderowane przy użyciu obrazów (można ustawić niestandardowe za pomocą CSS). Oto (niezaznaczone) pole wyboru w FireFox, podświetlone za pomocą inspektora DOM:
A oto to samo niestylowane pole wyboru w Chrome:
Możesz zobaczyć margines (pomarańczowy); wypełnienie nie jest obecne (byłoby pokazane na zielono). Więc co to za pseudo-margines po prawej i na dole pola wyboru? Są to części obrazu użyte dla pola wyboru . Dlatego używanie po prostu vertical-align: middle
tak naprawdę nie wystarcza i jest to przyczyną problemów w różnych przeglądarkach.
Co więc możemy z tym zrobić?
Jedną z oczywistych opcji jest - zastąp zdjęcia! Na szczęście można to zrobić za pomocą CSS i zastąpić je obrazami zewnętrznymi, obrazami base64 (in-CSS), svg w CSS lub po prostu pseudoelementami. Jest to solidne podejście (w różnych przeglądarkach!), A oto przykład takiej korekty skradzionej z tego pytania :
.checkbox-custom {
opacity: 0;
position: absolute;
}
.checkbox-custom,
.checkbox-custom-label {
display: inline-block;
vertical-align: middle;
margin: 5px;
cursor: pointer;
}
.checkbox-custom + .checkbox-custom-label:before {
content: '';
display: inline-block;
background: #fff;
border-radius: 5px;
border: 2px solid #ddd;
vertical-align: middle;
width: 10px;
height: 10px;
padding: 2px;
margin-right: 10px;
text-align: center;
}
.checkbox-custom:checked + .checkbox-custom-label:before {
width: 1px;
height: 5px;
border: solid blue;
border-width: 0 3px 3px 0;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
border-radius: 0px;
margin: 0px 15px 5px 5px;
}
<div>
<input id="checkbox-1" class="checkbox-custom" name="checkbox-1" type="checkbox">
<label for="checkbox-1" class="checkbox-custom-label">First Choice</label>
</div>
<div>
<input id="checkbox-2" class="checkbox-custom" name="checkbox-2" type="checkbox">
<label for="checkbox-2" class="checkbox-custom-label">Second Choice</label>
</div>
Możesz przeczytać bardziej szczegółowe artykuły na temat takich stylizacji, takie jak niektóre wymienione tutaj ; jest poza zakresem tej odpowiedzi.
Ok, nadal co z rozwiązaniem no-custom-images-or-pseudo-elements?
TL; DR: wygląda na to, że to nie zadziała, zamiast tego użyj niestandardowego pola wyboru
Po pierwsze, zauważmy, że jeśli w innych przeglądarkach te pseudo-marginesy wewnątrz ikony pola wyboru były dowolne, nie byłoby spójnego rozwiązania. Aby go zbudować, musimy zbadać anatomię takich obrazów w istniejących przeglądarkach.
Więc jakie przeglądarki mają pseudo-marginesy w polach wyboru? Sprawdziłem Chrome 75, Vivaldi 2.5 (oparty na Chromium), FireFox 54 (nie pytaj, dlaczego tak nieaktualny), IE 11, Edge 42, Safari ?? (pożyczyłem jeden na minutę, zapomniałem sprawdzić wersję). Tylko Chrome i Vivaldi mają takie pseudo-marginesy (podejrzewam również, że wszystkie przeglądarki oparte na Chromium, takie jak Opera).
Jaki jest rozmiar tych pseudo-marginesów? Aby to rozgryźć, można użyć powiększonego pola wyboru:
input {
zoom: 10;
box-shadow: 0 0 1px inset #999;
}
<input type=checkbox>
mój wynik to ~ 7% szerokości / wysokości, a zatem 0,9-1,0px w jednostkach bezwzględnych. Dokładność może jednak zostać zakwestionowana: wypróbuj różne wartości zoom
dla pola wyboru. W moich testach zarówno w Chrome, jak i Vivaldi, względny rozmiar pseudo-marginesu jest bardzo różny dla zoom
wartości 10, 20 i dla wartości 11-19 (??):
scale
wydaje się bardziej spójny:
input {
transform: scale(10) translate(50%, 50%);
box-shadow: 0 0 1px inset #999;
}
<input type=checkbox>
więc prawdopodobnie ~ 14% i 2px są poprawnymi wartościami.
Teraz, gdy wiemy (?) Rozmiar pseudo-marginesu, zauważmy, że to nie wystarczy. Czy rozmiary ikon pól wyboru są takie same dla wszystkich przeglądarek? Niestety! Oto, co pokazuje inspektor DOM dla niestylowanych pól wyboru:
- FireFox: 13,3px
- Oparty na chromie : 12,8 pikseli za całość, stąd 12,8 (100% - 14%) = 11 pikseli za to, co jest wizualnie postrzegane jako pole wyboru
- IE 11, Edge: 13px
- Safari: nie dotyczy (uważam, że należy je porównać na tym samym ekranie)
Zanim omówimy jakieś rozwiązania lub sztuczki, zapytajmy: co to jest prawidłowe wyrównanie? Co staramy się osiągnąć? Do pewnego stopnia jest to kwestia gustu, ale w zasadzie mogę myśleć o następujących aspektach „miłych” dopasowań:
tekst i pole wyboru na tej samej linii bazowej (celowo nie zmieniam tutaj pola wyboru):
lub mają tę samą środkową linię pod względem małych liter:
lub ta sama środkowa linia pod względem wielkich liter (łatwiej zobaczyć różnicę dla różnych rozmiarów czcionek):
a także musimy zdecydować, czy rozmiar pola wyboru powinien być równy wysokości małej litery, dużej litery lub czegoś innego (większy, mniejszy lub między małymi a dużymi).
W tej dyskusji nazwijmy wyrównanie ładnym, jeśli pole wyboru znajduje się na tej samej linii bazowej co tekst i ma wielkość dużej litery (wysoce dyskusyjny wybór):
Teraz jakie narzędzia musimy:
- dostosuj rozmiar pola wyboru
- rozpoznaj Chromium za pomocą jego pseudo-marginesowego pola wyboru i ustaw określone style
- dostosuj wyrównanie pionowe pola wyboru / etykiety
?
Jeśli chodzi o regulację wielkości pola wyboru : istnieją width
, height
, size
, zoom
, scale
(mieć coś przeoczyłem?). zoom
i scale
nie pozwalają ustawiać rozmiaru bezwzględnego, więc mogą pomóc tylko w dostosowaniu do rozmiaru tekstu, a nie ustawiać rozmiaru w różnych przeglądarkach (chyba że możemy napisać reguły specyficzne dla przeglądarki). size
nie działa z Chrome (czy działało ze starą IE? zresztą to nie jest takie interesujące). width
i height
działamy w Chrome i innych przeglądarkach, więc możemy ustawić wspólny rozmiar, ale znowu w Chrome ustawia rozmiar całego obrazu, a nie samego pola wyboru. Uwaga: minimalna (szerokość, wysokość) określa rozmiar pola wyboru (jeśli szerokość ≠ wysokość, pole poza kwadratem pola wyboru jest dodawane do „pseudo-marginesu”).
Niefortunne jest to, że pseudo-marginesy w Chrome nie są ustawione na zero dla żadnej szerokości i wysokości, o ile widzę.
Obawiam się, że obecnie nie ma niezawodnej metody opartej tylko na CSS .
Rozważmy wyrównanie pionowe. vertical-align
nie może dać spójnych wyników po ustawieniu na middle
lub z baseline
powodu pseudo-marginesu Chrome, jedyną realną opcją uzyskania tego samego „układu współrzędnych” dla wszystkich przeglądarek jest wyrównanie etykiety i danych wejściowych do top
:
(na zdjęciu: wyrównanie w pionie: góra, dół i dół bez cienia)
Jaki więc z tego wynikniemy?
input[type="checkbox"] {
height: 0.95em;
width: 0.95em;
}
label, input {
vertical-align: top;
}
<label><input type="checkbox">label</label>
Powyższy fragment działa z Chrome (przeglądarki oparte na Chromium), ale inne przeglądarki wymagają mniejszego rozmiaru pola wyboru. Wydaje się, że niemożliwe jest dostosowanie zarówno rozmiaru, jak i wyrównania w pionie w sposób, który działa wokół dziwactwa obrazu pola wyboru Chromium. Moja ostatnia propozycja to: zamiast tego użyj niestandardowych pól wyboru - unikniesz frustracji :)