Felix Riesterer: Problem mit Toggle-Button

Beitrag lesen

Lieber jbaben,

das class-Attribut gibt Dir die Möglichkeit, alle Elemente, die diese Klasse haben, mit dafür passenden Regeln zu stylen. Ein zweiter Button sollte also eigentlich kein Problem sein. Lass uns schauen, wo Du genau scheiterst.

  <!-- Toogle-Button GEYSER ON/OFF -->
      .onoffswitch {
        position: relative; width: 140px;
        -webkit-user-select:none; -moz-user-select:none; -ms-user-select: none;
    }

Dein CSS-Code enthält ungültige Code-Teile. Ein HTML-Kommentar ist nur in HTML ein Kommentar, in CSS notiert man Kommentare anders.

Dein CSS-Code geht also von einem Element aus, das die Klasse onoffswitch hat. In Deinem HTML ist das ein <div>:

<div class="onoffswitch">
  <input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch" checked>
  <label class="onoffswitch-label" for="myonoffswitch">
    <span class="onoffswitch-inner"></span>
    <span class="onoffswitch-switch"></span>
  </label>
</div>

Es handelt sich hier also um verschiedene Elemente, die alle unter dem Elternelement mit der Klasse onoffswitch versammelt sind. Ein Klonen sollte bereits einen zweiten Toggle-Button ergeben:

<div class="onoffswitch">
  <input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch" checked>
  <label class="onoffswitch-label" for="myonoffswitch">
    <span class="onoffswitch-inner"></span>
    <span class="onoffswitch-switch"></span>
  </label>
</div>
<!-- zweiter Toggle-Button mit anderem name-Attributwert: -->
<div class="onoffswitch">
  <input type="checkbox" name="onoffswitch2" class="onoffswitch-checkbox" id="myonoffswitch2" checked>
  <label class="onoffswitch-label" for="myonoffswitch2">
    <span class="onoffswitch-inner"></span>
    <span class="onoffswitch-switch"></span>
  </label>
</div>

Warum scheitert das bei Dir? Oder scheitert es nicht und Du hast eigentlich ein anderes (visuelles?) Problem?

Was mir sonst noch so aufgefallen ist, sind die vielen Klassen-Namen, die eigentlich die Sache nur verkomplizieren:

  • class="onoffswitch"
  • class="onoffswitch-checkbox"
  • class="onoffswitch-label"
  • class="onoffswitch-inner"
  • class="onoffswitch-switch"

Genau genommen genügt die Klasse onoffswitch für alles. Man kann in CSS nämlich mittels des Nachfahren-Selektors ebenso auf onoffswitch-checkbox oder onoffswitch-label einwirken. Die beiden <span> innerhalb von <label> kann man mit nth-of-type() selektieren, so dass Dein CSS vielleicht etwas komplizierter aussehen mag (wenn man es vernünftig formatiert, ist es sogar noch übersichtlicher), dafür aber das HTML besser klonbar:

<div class="onoffswitch">
  <input type="checkbox" name="onoffswitch" id="myonoffswitch" checked>
  <label for="myonoffswitch">
    <span></span>
    <span></span>
  </label>
</div>
<!-- zweiter Toggle-Button mit anderem name-Attributwert: -->
<div class="onoffswitch">
  <input type="checkbox" name="onoffswitch2" id="myonoffswitch2" checked>
  <label for="myonoffswitch2">
    <span></span>
    <span></span>
  </label>
</div>

Und nun das verbesserte CSS:

/* Toogle-Button GEYSER ON/OFF */

/* Das Elternelement, das den Button realisiert */
.onoffswitch {
  position: relative;
  width: 140px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
}

/* das <input> Element */
.onoffswitch input {
 display: none;
}

/* das <label> Element */
.onoffswitch label {
  display: block;
  overflow: hidden;
  cursor: pointer;
  border: 2px solid #999999;
  border-radius: 20px;
}

/* das erste <span> Element */
.onoffswitch span:nth-of-type(1) {
  display: block;
  width: 200%;
  margin-left: -100%;
  transition: margin 0.3s ease-in 0s;
}

.onoffswitch span:nth-of-type(1):before,
.onoffswitch span:nth-of-type(1):after {
  display: block;
  float: left;
  width: 50%;
  height: 40px;
  padding: 0;
  line-height: 40px;
  font-size: 14px;
  color: white;
  font-family: Trebuchet, Arial, sans-serif;
  font-weight: bold;
  box-sizing: border-box;
}

.onoffswitch span:nth-of-type(1):before {
  content: "GEYSER ON";
  padding-left: 10px;
  background-color: #0000FF; color: #FFFFFF;
}

.onoffswitch span:nth-of-type(1):after {
  content: "GEYSER OFF";
  padding-right: 10px;
  background-color: #FF0000;
  color: #00FF00;
  text-align: right;
}

/* das zweite <span> Element */
.onoffswitch span:nth-of-type(2) {
  display: block;
  width: 20px;
  margin: 10px;
  background: #FFFFFF;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 96px;
  border: 2px solid #999999;
  border-radius: 20px;
  transition: all 0.3s ease-in 0s; 
}

.onoffswitch input:checked + label span:nth-of-type(1) {
  margin-left: 0;
}

.onoffswitch input:checked + label span:nth-of-type(2) {
  right: 0px; 
}

Damit sollte es besser klappen. [Beweis]

Liebe Grüße,

Felix Riesterer.