Vor kurzem hatte ich einen kurzen Job in der Entwicklung technischer Spezifikationen für die Modernisierung eines langjährigen Projekts. Insbesondere betraf der Fall das Styling des berüchtigten <input type = "checkbox">. Es stellte sich heraus, dass der Darsteller, ein Programmierer "aller Berufe", nicht einmal verstand, dass ich ihm in Worten erklärte, wie es geht. Ich musste Beispiele machen und als Ergebnis erschien dieser Text.
Ich möchte Sie daran erinnern, dass das Kontrollkästchen und die Radiobox jetzt von verschiedenen Standorten unterschiedlich angezeigt werden. Es kommt vor, dass eine nicht markierte Eingabe nicht sofort erkannt werden kann - sie ist so "Designer-schön", und in den neuesten Versionen von Chrome haben die ausgewählten Kontrollkästchen eine abscheuliche Cyan-Farbe erhalten.
Also die Situation
Es gibt drei Unternehmen, die ein bestimmtes Softwareprodukt in Bezug auf Bestellungen, Buchhaltung, Lager usw. verwenden. Die Zusammenarbeit mit Kunden, Partnern, Darstellern usw.
Vermarkter und Werbetreibende verwenden es ebenfalls. Was dieses System tut - egal was es sagt - es spielt keine Rolle.
Und es ist wichtig, dass die Site dieses Produkts viele Seiten mit Formularen enthält, auf denen sich viele Eingabe-Kontrollkästchen und Radio befinden.
Beschwerden von Mitarbeitern
Regie : Auf der großen Leinwand sind die "Kryzhiki" schwer zu sehen und nicht wahrnehmbar.
Hauptbuchhalter : Auf meinem Computer sieht das „Kryzhiki“ so aus, auf den Mitarbeitern sieht es anders aus, zu Hause ist es auch anders, aber auf dem Tablet ist es völlig anders.
Vermarkter : Ist es möglich, dass einige nicht ausgewählte Positionen rot und andere ausgewählt grün sind?
Etc.
Also die Aufgabe
- Korrigieren Sie das Erscheinungsbild des Kontrollkästchens und der Radiobox mit minimalen Kosten und minimalen Änderungen.
- Erstellen Sie ein Kontrollkästchen und ein Radiobox-Styling für verschiedene Benutzer. Wichtig: Dies ist eine geschlossene Seite, es gibt "alle unsere", "Schönheit" wird nicht benötigt, aber Effizienz der Wahrnehmung ist erforderlich.
Was ist nicht erlaubt
1. Die Serverseite darf nicht berührt werden.
2. Sie können keine Javascript-Dateien berühren, Sie können kein eigenes Javascript einfügen.
3. Die CSS-Dateien können nicht berührt werden.
Was ist erlaubt
1. Bearbeiten Sie HTML-Vorlagen.
2. Erstellen Sie eine Stildatei für alle Benutzer.
4. Erstellen Sie eine Stildatei für einen bestimmten Benutzer oder eine bestimmte Benutzergruppe.
Und was Sie getan haben, können Sie sofort auf codepen.io sehen , aber es ist besser, weiterzulesen .
Vorstudie zeigte
1. Fast alle <input type = "checkbox"> haben ein Namensfeld und diejenigen, die keine ID haben.
2. Alle <input type = "radio"> haben ein Namensfeld, einige eine ID.
3. Dementsprechend kann in CSS auf das Kontrollkästchen sowohl nach ID als auch nach Name zugegriffen werden. Zum Radio - entweder nach ID oder nach der Nummer des Kindes des Elternteils.
Quellcode-Schnipsel:
/* 1 */
<tag><input type="checkbox"> </tag>
/* 2 */
<tag><input type="checkbox"> <br>
<input type="checkbox"> </tag>
/* 3 */
...<label><input type="checkbox"> </label>...
/* 4 */
<td><input id="idxxx" type="checkbox"></td>
<td><label for="idxxx"> </label></td>
Lassen Sie uns den Code korrigieren:
/* 1 */
<tag><label class="new-input"><input type="checkbox"><s></s><span> </span></label></tag>
/* 2 */
<tag><label class="new-input"><input type="checkbox"><s></s><span> </span></label><br>...</tag>
/* 3 */
...<label class="new-input"><input type="checkbox"><s></s><span> </span></label>...
/* 4 */
<td><label class="new-input new-input-one"><input id="idxxx" type="checkbox"><s></s></label></td>
<td><label for="idxxx"> </label></td>
Für <input type = "radio"> ist alles gleich, die LABEL-Klasse ist gleich.
Was genau hast du gemacht?
- Jede Eingabe (Heck von Option 3) wurde mit einem LABEL-Tag unserer Klasse versehen. Option 3 hat gerade eine Klasse hinzugefügt.
- Unmittelbar nach der Eingabe haben wir ein leeres S-Tag eingefügt. Da die Eingabe selbst nicht sichtbar ist, wird diese Eingabe von diesem Tag gerendert.
- Der Begleittext wurde mit dem SPAN-Tag versehen (mit Ausnahme von Option 4). Dieses Tag wird benötigt, wenn wir die Frage der Ausrichtung der visuellen Eingabe relativ zu diesem Text entscheiden.
- Option 4 wurde eine weitere Klasse hinzugefügt, um diese Ausrichtung zu vermeiden, da sich der zugehörige Text in einer anderen Zelle der Tabelle befindet. Genau genommen wäre es notwendig, das Gegenteil zu tun - fügen Sie eine Klasse hinzu, die für die Ausrichtung der Optionen 1-3 verantwortlich ist. Aber es gibt viel mehr Optionen 1-3 als die 4., und um das HTML nicht aufzublasen, wird es so gemacht.
Rhetorische Fragen und rhetorische Antworten
1. S? , S – . , input.
2. S SPAN ? , html? , , «» .
3. , , «» html . – mni mnio. :-))
2. S SPAN ? , html? , , «» .
.new-input > S { }
.new-input > .new-input-S {}
3. , , «» html . – mni mnio. :-))
Einige vorläufige Überlegungen und CSS-Optimierungen in Bezug auf die Box-Größe: Border-Box-, LABEL-Normalisierung, A + B-, A ~ B- und [attr] -Selektoren: überprüft, deaktiviert und :: vor Pseudoklassen. Wer sich nicht sicher ist, was er weiß oder sein Wissen auffrischen will, schaut unter den Schnitt.
Vorüberlegungen
1. , «» css (box-sizing:content-box) width height , padding border . box-sizing:border-box , padding border width height.
2. , , «» . «» LABEL , . LABEL.
.., box-sizing:border-box LABEL, . ( ).
3. «A + B» , B, A, .. B. , «A ~ B» , B A, .. .
, «».
?
– S SPAN.
– INPUT .
– INPUT .
– INPUT .
, , – S , input radio.
, S SPAN input.
4. S input, input display:none, , LABEL , S . html hidden input? , hidden input «» , html .
2. , , «» . «» LABEL , . LABEL.
LABEL {
box-sizing:border-box; cursor:pointer; user-select:none;
}
LABEL *,
LABEL *::before,
LABEL *::after {
box-sizing:inherit;
}
.., box-sizing:border-box LABEL, . ( ).
3. «A + B» , B, A, .. B. , «A ~ B» , B A, .. .
, «».
?
<label class="new-input"><input type="checkbox"><s></s><span> </span></label>
<label class="new-input"><input type="radio"><s></s><span> </span></label>
/* 1 */
.new-input > INPUT + S {}
.new-input > INPUT ~ SPAN {}
/* 2 */
.new-input > INPUT:not(:checked) + S {}
.new-input > INPUT:not(:checked) ~ SPAN {}
/* 3 */
.new-input > INPUT:checked + S {}
.new-input > INPUT:checked ~ SPAN {}
/* 4 */
.new-input > INPUT:disabled + S {}
.new-input > INPUT:disabled ~ SPAN {}
/* 5 */
.new-input > INPUT[type="radio"] + S {}
– S SPAN.
– INPUT .
– INPUT .
– INPUT .
, , – S , input radio.
, S SPAN input.
4. S input, input display:none, , LABEL , S . html hidden input? , hidden input «» , html .
Beginnen wir also mit dem Rendern der Eingabe
Beispiel N 1. Das einfachste - wir verwenden alphabetische Zeichen. Der
HTML-Code ist derselbe und das CSS sieht folgendermaßen aus:
/* s1 */
.new-input > INPUT + S::before {
content: "c";
}
/* s2 */
.new-input > INPUT:checked + S::before {
content: "V";
}
/* s3 */
.new-input > INPUT[type="radio"] + S::before {
content: "r";
}
/* s4 */
.new-input > INPUT[type="radio"]:checked + S::before {
content: "X";
}
/* s5 */
.new-input > INPUT:disabled + S::before {
opacity: 0.5;
}
/* s6 */
.new-input > S {
text-decoration: none;
margin-left: 3px;
margin-right: 6px;
}
/* s7 */
.new-input > S::before {
display: inline-block;
width: 1.25em;
text-align: center;
color: #fafafa;
background-color: #37474f;
}
/* s8 */
.new-input > INPUT[type="radio"] + S::before {
border-radius: 50%;
}
Das S-Tag rendert die Eingabe. Aber wir werden es durch die Funktionalität "teilen": Das S- Tag selbst ist für die Platzierung in LABEL und die Ausrichtung relativ zum nächsten SPAN verantwortlich.
Und das Pseudoelement S :: before wird innerhalb des S-Tags platziert und fungiert als Eingabe.
Die Zeile s1 definiert, welches Zeichen zuvor in S :: platziert wird, wenn keine Eingabe ausgewählt ist. Im Prinzip wäre es notwendig, ".new-input> INPUT: not (: checked) + S :: before" zu schreiben, aber einige Browser (z. B. IE) führen eine solche Konstruktion möglicherweise nicht aus.
String s2 definiert das Zeichen, wenn die Eingabe ausgewählt ist.
Die Leitungen s3 und s4 machen dasselbe für das Eingangsradio.
String s5beschreibt, was passiert, wenn die Eingabe blockiert wird - in diesem Fall ist das S-Tag halbtransparent.
Die Linie s6 definiert die Ausrichtung. In diesem Fall wird links und rechts aufgefüllt (nur in diesem Beispiel). Außerdem wird das regelmäßige Durchstreichen entfernt.
Die Linie s7 bildet ein Quadrat, s8 verwandelt es in einen Kreis für das Eingangsradio.
Beispiel 1 kann unter codepen.io eingesehen werden . Es gibt native und neue Eingaben. Ersteres kann entfernt werden.
Ein bisschen mehr Details zur Anzeige: Inline-Block, Schriftgröße, Zeilenhöhe
font-size, line-height. line-height – font-size, line-height – , line-height – . line-height:1.25, S::before width:1.25em.
S::before display: inline-block – S::before «» ( , , .), «» . .
S::before display: inline-block – S::before «» ( , , .), «» . .
Frage:
Können Sie Sonderzeichen verwenden? So:
□ ■ ▢ ○ ○ ● ◎ ◉
Geben Sie ihnen die richtige Größe und fertig . Nein?
Antwort:
Sie können. Aber das musst du nicht. Denn es wird große Hämorrhoiden und Tänze mit Tamburinen geben, wenn die gewünschte Größe, vertikale Ausrichtung, Trimmung usw. zugewiesen werden. Außerdem arbeiten verschiedene Browser mit diesen Symbolen unterschiedlich.
Wir gingen den anderen Weg. Obwohl das letzte Beispiel eine Implementierung dieser Idee enthält.
Beispiel N 2. Eingabeelemente mit CSS "zeichnen". Der
HTML-Code ist derselbe, aber der CSS sieht folgendermaßen aus:
/* s1 */
.new-input > S::before {
content: "";
display: inline-block;
width: 0.75em;
height: 0.75em;
border: 1px solid currentColor;
padding: 2px;
background-clip: content-box;
border-radius: 20%;
}
/* s2 */
.new-input > INPUT[type="radio"] + S::before {
border-radius: 50%;
}
/* s3 */
.new-input > INPUT:checked + S::before {
background-color: currentColor;
}
/* s4 */
.new-input > INPUT:disabled + S::before {
opacity: 0.5;
}
/* s5 */
.new-input > S {
text-decoration: none;
margin-left: 3px;
margin-right: 6px;
}
Die Zeile s1 definiert S :: before, um Eingaben zu rendern. Dies ist ein Inline-Block, dessen Breite und Höhe auf 0,75 em eingestellt sind. Dies entspricht in etwa der Höhe des Großbuchstabens und hängt von der Schriftgröße des übergeordneten Zeichens ab. Ein dünner Rand wird mit der aktuellen Farbe, der inneren Polsterung und der kleinen Abrundung der Ecken gesetzt. Und das Wichtigste! - Eigenschaft Hintergrund-Clip: Inhaltsfeld ist gesetzt. Dies ist eine sehr interessante Eigenschaft. Wenn die Hintergrundfarbe festgelegt ist, wird nur der Inhaltsteil gezeichnet und die Polsterung wird nicht beeinflusst. Was wir brauchen.
Die s2- Leitung für einen Funkeingang macht S :: vor der Runde.
Die s3- Zeile für die markierte Eingabe setzt S :: vor der Hintergrundfarbe auf die aktuelle Farbe. Das heißt, es "zeichnet" ein Quadrat oder einen Kreis nach innen.
Linies4 entsperrt den Eingang, Zeile s5 füllt links und rechts auf.
Die Vorteile dieser Methode
- Alles ist sehr einfach. Funktioniert in allen Browsern. Sogar IE10 (in Emulation des 11.).
- Sie können färben, wie Sie möchten.
- Da S :: before ein Inline-Block ist, befindet es sich genau am
unteren Rand derGrundlinie und kommt nirgendwo davon ab. Wenn es größer als der Text ist, erhöht es einfach die Zeilenhöhe und bleibt auf der Grundlinie. - Da sich die Eingabevisualisierung innerhalb eines S-Tags befindet, kann sie einfach positioniert und ausgerichtet werden.
- Die Abmessungen von S :: before in em ermöglichen es, die Größe relativ zur Größe des Beschriftungstextes festzulegen. Sie können beispielsweise Grenzwerte für Höhe und Breite festlegen.
Nachteile dieser Methode
Hauptsächlich in em-Größen. Tatsache ist, dass eine Situation auftreten kann, in der die Breite und Höhe bei der Berechnung (von em bis px) einen Bruchwert haben. Auf normalen Computern mit normalem Bildschirm erfolgt die Rundung möglicherweise nicht richtig. Beispielsweise können die Abmessungen 12,8 x 12,8 Pixel in demselben Mozila 13 x 12 Pixel betragen. Dann müssen Sie feste Größen einstellen. Obwohl dies bei modernen Monitoren und Grafikkarten, Laptops, Tablets und Smartphones nicht der Fall ist, besteht der Punkt (Pixel) des Browsers aus mehreren Bildschirmpixeln.
Beispiel 2 kann unter codepen.io eingesehen werden . Es gibt native und neue Eingaben. Ersteres kann entfernt werden.
Die erste Aufgabe - das Rendern der Eingabe - ist also erledigt. Wir gehen zur ausgewählten "Färbung" über.
Farbeingabe
HTML zum Beispiel:
<label class="new-input"><input name="chb1" type="checkbox" ...><s></s><span> </span></label>
<label class="new-input"><input id="rb1" type="radio" ...><s></s><span> </span></label>
Wir verweisen auf eine Eingabe des Kontrollkästchentyps nach Namen und auf Radio nach ID.
Wir malen alles blau
/* input */
.new-input > INPUT[name="chb1"] + S,
.new-input > INPUT#rb1 + S {
color: #0091ea;
}
/* text */
.new-input > INPUT[name="chb1"] ~ SPAN,
.new-input > INPUT#rb1 ~ SPAN {
color: #0091ea;
}
/* */
.new-input > INPUT[name="chb1"] ~ *,
.new-input > INPUT#rb1 ~ * {
color: #0091ea;
}
Denken Sie an die Spezifität in CSS. Diese Stile sind spezifischer als die grundlegenden und funktionieren auf jeden Fall. Wie unterscheiden sie sich von den oben beschriebenen? Diejenigen, die nur für ausgewählte Eingaben gelten - diejenigen, die den angegebenen Namen und ID-Wert haben.
Hier ist alles in Ordnung, außer dass die nicht ausgewählten Eingänge nicht sehr gut aussehen - der dünne blaue Rand ist kaum wahrnehmbar.
Färben Sie es grün, wenn die Eingabe ausgewählt ist
/* input */
.new-input > INPUT[name="chb1"]:checked + S,
.new-input > INPUT#rb1:checked + S {
color: #00c853;
}
/* text */
.new-input > INPUT[name="chb1"]:checked ~ SPAN,
.new-input > INPUT#rb1:checked ~ SPAN {
color: #00c853;
}
/* */
.new-input > INPUT[name="chb1"]:checked ~ *,
.new-input > INPUT#rb1:checked ~ * {
color: #00c853;
}
Die erste Option ist meiner Meinung nach nicht sehr gut - sowohl der Rahmen als auch das innere Quadrat / der Kreis sind grün. Sie können es nur färben.
/* input */
.new-input > INPUT[name="chb1"]:checked + S::before,
.new-input > INPUT#rb1:checked + S::before {
background-color: #00c853;
}
Farbe rot, wenn Eingabe NICHT ausgewählt ist
/* input */
.new-input > INPUT[name="chb1"]:not(:checked) + S,
.new-input > INPUT#rb1:not(:checked) + S {
color: #d50000;
}
/* text */
.new-input > INPUT[name="chb1"]:not(:checked) ~ SPAN,
.new-input > INPUT#rb1:not(:checked) ~ SPAN {
color: #d50000;
}
/* */
.new-input > INPUT[name="chb1"]:not(:checked) ~ *,
.new-input > INPUT#rb1:not(:checked) ~ * {
color: #d50000;
}
Ist die Logik klar? Sie können weiterhin komplexere Designs erstellen.
Wenn beispielsweise keine Eingabe ausgewählt ist, sollte der Text rot und fett sein, und wenn das innere Eingabeelement und der Text ausgewählt sind, sollte er grün sein. Grundstufe!
/* , */
.new-input > INPUT[name="chb1"]:not(:checked) ~ SPAN,
.new-input > INPUT#rb1:not(:checked) ~ SPAN {
color: #d50000;
font-weight: bold;
}
/* input, */
.new-input > INPUT[name="chb1"]:checked + S::before,
.new-input > INPUT#rb1:checked + S::before {
background-color: #00c853;
}
/* , */
.new-input > INPUT[name="chb1"]:checked ~ SPAN,
.new-input > INPUT#rb1:checked ~ SPAN {
color: #00c853;
}
Und zum Beispiel müssen Sie eine ganze Gruppe von Eingaben (10-15 Teile) verarbeiten. Um keine Zeilen zu schreiben, können Sie das gemeinsame übergeordnete Element (.parent_element) finden und die Bedingung verkürzen.
.parent_element > .new-input > INPUT:not(:checked) ~ SPAN {
color: #d50000;
font-weight: bold;
}
.parent_element > .new-input > INPUT:checked + S::before {
background-color: #00c853;
}
.parent_element > .new-input > INPUT:checked ~ SPAN {
color: #00c853;
}
Sie können alles im letzten Beispiel auf codepen.io sehen.
Hier scheint es, und das war's. Es bleibt nur, die Muttermale des Perfektionisten zu "kratzen" - die Probleme der Ausrichtung.
Richten Sie visuelle Eingaben und Begleittext aus
Lassen Sie mich zunächst an bekannte Dinge über Textplatzierung, Formatierung und mehr erinnern. Alles ist unter dem Schnitt.
Bekannte Dinge
, , css . .
1. font-size , . (baseline), «» . «» – g – «» . (cap height) – «» () . «» – – «» . , , . «» 75% . , font-size:16px, Arial 12px. , «» .
2. line-height . , font-size, , . , .
3. , S SPAN font-size line-height - . font-size:16px line-height:1.25. N1 S::before 1.25em, . N2 ( ) – S::before 0.75em, . font-size . , .
4. - «», , . . , , 50%. , , 150%. -, / – -! , -.
? , , input — , , , . !
1. font-size , . (baseline), «» . «» – g – «» . (cap height) – «» () . «» – – «» . , , . «» 75% . , font-size:16px, Arial 12px. , «» .
2. line-height . , font-size, , . , .
3. , S SPAN font-size line-height - . font-size:16px line-height:1.25. N1 S::before 1.25em, . N2 ( ) – S::before 0.75em, . font-size . , .
4. - «», , . . , , 50%. , , 150%. -, / – -! , -.
? , , input — , , , . !
Was passiert, wenn der Begleittext in SPAN in zwei oder drei Zeilen angezeigt wird? Offensichtlich wird es unter Eingabe "passen". Es ist nicht schön, es muss repariert werden.
Eine alte Methode ist folgende: Das S-Tag ist float: left und das SPAN-Tag ist display: block und overflow: hidden.
Dadurch wird eine Textspalte erstellt. Es wird davon ausgegangen, dass einige von ihnen einen angemessenen Spielraum haben, wodurch ein Sprung zwischen ihnen entsteht. Nun, es gibt auch Hämorrhoiden mit der Beendigung des Floats nach SPAN. Wir werden den modernen Weg einschlagen - Flexbox verwenden. Er ist hier völlig fehl am Platz.
.new-input {
display: flex;
flex-direction: row;
align-items: start;
}
.new-input > S {
margin-right: 4px;
flex: 0 0 auto;
}
.new-input > SPAN {
flex: 0 1 auto;
}
In diesem Fall ist das LABEL-Tag (das eine neue Eingabe ist) flexibel, S und SPAN sind Blöcke, die oben auf dem LABEL platziert sind. Der Text in SPAN besteht bei Bedarf aus mehreren Zeilen. Aus diesem Grund wurde die visuelle Eingabe zuvor in S :: beschrieben. Unabhängig von der Höhe wird SPAN S :: before an der ersten SPAN-Linie ausgerichtet. Alternativ könnten Sie Ausrichtungselemente angegeben haben: Mitte - dann würde bei einem einzeiligen SPAN die visuelle Eingabe oben und bei zwei Zeilen in der Mitte und bei drei Zeilen in der zweiten Zeile angezeigt. Im letzten Beispiel können Sie die Position der Eingabe ändern.
Das ist alles
Ich hoffe es war interessant und nützlich für jemanden. Bitte schimpfen Sie nicht viel mit mir - dies ist meine erste Erfahrung auf Habr.
Beispiel 1 ist nur eine Demonstration der Wechselwirkung zwischen der Änderung der Eingabe und einem benachbarten Element.
Beispiel N 2 - Visualisierung der Eingabe mit CSS als Grundlage der Lösung.
Das letzte Beispiel ist alles zusammen beschrieben.
Über eine bestimmte Implementierung
Es gab umfangreiche Formulare, in denen die Feldblöcke, die von bestimmten Benutzern bearbeitet werden konnten, mit einem schwachen Hintergrund hervorgehoben wurden und der Rest der Eingabe die Eigenschaft disabled hatte und nur zur Information diente. Daher wurde der Stil ".new-input> INPUT: disabled + S :: before" nicht angewendet.
UPD
Als Antwort auf Kommentare Beispiel N 3 .
Es gibt Schlüssel- und Fokusunterstützung für versteckte Eingaben bei der Arbeit.