Unwanted behavior with CSS transition

Viewed 53

I have an Angular application. Its HTML file contains a div with class row which itself contains two divs with class col. By clicking on the button, the size of the columns change:

<button class="btn btn-primay" (click)="changeColumnsSize()"> change column sizes</button>
      <div class="row">
        <div id="leftColumn" class="col-sm-{{leftColumnSize}}" style="background-color:lavender;">
          .col-sm-8     
        </div>
        <div id ="rightColumn" *ngIf="this.state===true" class="col-sm-{{rightColumnSize}}" style="background-color:lavenderblush;">
          .col-sm-4
        </div>
      </div>

To have a smooth resize, I have added transition property to the col classes in the CSS file:

.col-sm-8 { transition: width .5s ease; }

.col-sm-4 { transition: width .5s ease ; }

The TS file (that contains the changeColumnsSize function) looks like this:

export class BoxComponent {
  leftColumnSize: number = 12;
  rightColumnSize: number = 0;
  colDifference: number = 4;
  state: boolean = false;

  constructor() { }

  changeColumnsSize(){
    if (this.state===false)
      this.state = true;
    else
      this.state = false;
    if(this.state===true) {
      this.leftColumnSize-=this.colDifference;
      this.rightColumnSize+=this.colDifference;
    }
    else if (this.state===false) {
      this.leftColumnSize+=this.colDifference;
      this.rightColumnSize-=this.colDifference;
     }
    }
  }

However, there is a problem. Every time the transition occurs, the rightColumn appears below the leftColumn, then moves up to the correct place.

Can you help me solving this? I prefer to solve this without using Angular animations.

1 Answers

That's because in v4 the grid layout is not based on width property (and box model) but on
flex-basis + max-width (and flexbox model).

You need to set the transition on both properties. Or, the lazy and wrong way: on all.

See it working:

function changeColSize() {
  $('.col-switcher > div').toggleClass('col-sm-4 col-sm-8')
}
.col-switcher>div {
  transition: max-width .3s cubic-bezier(.4, 0, .2, .1), 
              flex-basis .3s cubic-bezier(.4, 0, .2, .1);
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>

<div class="container">
  <button class="btn btn-primay" onclick="changeColSize()"> change column sizes</button>
  <div class="row col-switcher">
    <div id="leftColumn" class="col-sm-8" style="background-color:lavender;">
      .col-sm-8
    </div>
    <div id="rightColumn" *ngIf="this.state===true" class="col-sm-4" style="background-color:lavenderblush;">
      .col-sm-4
    </div>
  </div>
</div>

Related