Riccardo Camera
Riccardo Camera

Reputation: 1

CSS transition from left to right starting from the center

How do I make sure that the span starting from the center expands up and down. I do not know if I have explained myself, I attach the code so you can understand what I mean. Is there anyone who can help me?

body {
    font: caption;
    background-color: #f1f1f1;
    position: relative;
    height: 100%;
}
 
.first_switcher {
  display: inline-block;
  height: 38px;
  margin-top:50px;
  padding: 0px;
  background: dimgray;
  border-radius: 2px;
  width: 200px;
  border-radius: 38px;
  position: relative;
}
 
.first_switcher__input2{
  display: none;
}
.first_switcher__input1 {
  display: none;
}
 
.first_switcher__label1 {
  float: left;
  width: 100px;
  font-size: 12px;
  line-height: 38px;
  color: #ffffff;
  text-align: center;
  cursor: pointer;
  position: inherit;
  z-index: 10;
  transition: color 0.2s cubic-bezier(0.4, 0.0, 0.2, 1);
  will-change: transform;
}

.first_switcher__label2 {
  float: left;
  width: 100px;
  font-size: 12px;
  line-height: 38px;
  color: transparent;
  text-align: center;
  cursor: pointer;
  position: inherit;
  z-index: 10;
  transition: color 0.2s cubic-bezier(0.4, 0.0, 0.2, 1);
  will-change: transform;
}
 
.first_switcher__toggle {
  position: absolute;
  float: left;
  height: 0px;
  width: 0px;
  font-size: 12px;
  line-height: 38px;
  cursor: pointer;
  background-color: #000000;
  border-radius: 38px;
  left: 0px;
  top: 14px;
  transition: left 0.25s cubic-bezier(0.4, 0.0, 0.2, 1);
  will-change: transform;
}

.first_switcher__input1:checked + .first_switcher__label1 {
  color: white;
}
.first_switcher__input2:checked + .first_switcher__label2 {
  transition-delay: 1s;
  color: white;
}

.first_switcher__input1:not(:checked) + .first_switcher__label1 {
  color: transparent;
}
.first_switcher__input2:checked ~ .first_switcher__toggle {
  -webkit-transition: width 2s, height 2s;
    transition: width 2s, height 2s;
  
  height: 38px;
  width: 200px; 
  left: 0px;
}
<div class="first_switcher">
                <input type="radio" name="balance" id="on" class="first_switcher__input1" checked/>
                    <label for="on" class="first_switcher__label1">ON</label>
      
                <input type="radio" name="balance" id="off" class="first_switcher__input2"/>
                    <label for="off" class="first_switcher__label2">OFF</label>
      
                <span class="first_switcher__toggle"></span>
            </div>

Upvotes: 0

Views: 312

Answers (1)

Temani Afif
Temani Afif

Reputation: 272772

You need to animate width/height and also top at the same time to keep the element in the center while growing

body {
  font: caption;
  background-color: #f1f1f1;
  position: relative;
  height: 100%;
}

.first_switcher {
  display: inline-block;
  height: 38px;
  margin-top: 50px;
  padding: 0px;
  background: dimgray;
  border-radius: 2px;
  width: 200px;
  border-radius: 38px;
  position: relative;
}

.first_switcher__input2 {
  display: none;
}

.first_switcher__input1 {
  display: none;
}

.first_switcher__label1 {
  float: left;
  width: 100px;
  font-size: 12px;
  line-height: 38px;
  color: #ffffff;
  text-align: center;
  cursor: pointer;
  position: inherit;
  z-index: 10;
  transition: color 0.2s cubic-bezier(0.4, 0.0, 0.2, 1);
  will-change: transform;
}

.first_switcher__label2 {
  float: left;
  width: 100px;
  font-size: 12px;
  line-height: 38px;
  color: transparent;
  text-align: center;
  cursor: pointer;
  position: inherit;
  z-index: 10;
  transition: color 0.2s cubic-bezier(0.4, 0.0, 0.2, 1);
  will-change: transform;
}

.first_switcher__toggle {
  position: absolute;
  height: 0px;
  width: 0px;
  font-size: 12px;
  line-height: 38px;
  cursor: pointer;
  background-color: #000000;
  border-radius: 38px;
  left: 0; /* updated */
  top: 50%; /* updated */
  transition: all 0.25s cubic-bezier(0.4, 0.0, 0.2, 1);
  will-change: transform;
}

.first_switcher__input1:checked+.first_switcher__label1 {
  color: white;
}

.first_switcher__input2:checked+.first_switcher__label2 {
  transition-delay: 1s;
  color: white;
}

.first_switcher__input1:not(:checked)+.first_switcher__label1 {
  color: transparent;
}

.first_switcher__input2:checked~.first_switcher__toggle {
  transition: all 2s; /* updated */
  height: 38px; 
  width: 200px;
  left: 0; /* updated */
  top: calc(50% - 19px); /* updated */
}
<div class="first_switcher">
  <input type="radio" name="balance" id="on" class="first_switcher__input1" checked/>
  <label for="on" class="first_switcher__label1">ON</label>

  <input type="radio" name="balance" id="off" class="first_switcher__input2" />
  <label for="off" class="first_switcher__label2">OFF</label>

  <span class="first_switcher__toggle"></span>
</div>

Upvotes: 1

Related Questions