Joe
Joe

Reputation: 4234

CSS animation without defining height, angular

I have a side pane with a pan out for each item. Similiar to this one https://angular.io/docs/js/latest/api/.

When I click on an item, I would like it to make a smooth transition animation.

My markup:

<div ng-repeat="item in mainCategories"
     class="main-list"
     ng-class="{'not-selected': item !== currentMainCategory}"
     >
    <p>{{item.title}}</p>
  </div>

  <div class="sub-categories">
    <div ng-repeat="subCategory in item.subCategories" class="sub-categories-content" ng-click="setSubCategory(subCategory)">
      <p>{{subCategory.title}}</p>
    </div>
  </div>
</div>

When an item is not selected, it has class not selected added to it.

This is my css:

.main-list{
   //I need to define a height here
   transition: 200ms cubic-bezier(0.4, 0, 1, 1);
 }

.not-selected{
  height:50px;
}

So the height is 50px when no item is selected. When an item is selected, the height is depending on how many items is in the current subcategory.

The problem is, when I can't define the height, the animation is not working. Is there any height property I can give to the .main-list, so the animation is working?

Upvotes: 0

Views: 95

Answers (2)

jme11
jme11

Reputation: 17374

Here's a simple example of how to use ng-style as suggested in my comments. Run the snippet below to see it in action and view the corresponding CSS.

  <div ng-repeat="item in main">
    <div class="maincat" ng-click="active($index)">
      <p>{{item.title}}</p>
    </div>
    <div class="animate" ng-style="{height: item.active ? item.sub.length*30+'px' : '0px'}">
      <div ng-repeat="subitem in item.sub" class="subcat">
        <p>{{subitem.title}}</p>
      </div>
    </div>
  </div>

var app = angular.module('demo.app', ['ngAnimate']);

app.controller('MainCtrl', ['$scope', function($scope){
  $scope.main = [{title: 'main1', sub: [{title: 'sub1'}, {title: 'sub2'}, {title: 'sub3'}]},{title: 'main2', sub: [{title: 'sub1'}, {title: 'sub2'}]}];
  $scope.active = function(idx) {
    $scope.main[idx].active = !$scope.main[idx].active;
  };
}]);
@import url("//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css");

.maincat {
  height: 30px;
  background-color: #ccc;
  width: 50%;
  padding: 3px 5px;
  cursor: pointer;
  border-bottom: 1px solid #555;
}

.subcat {
  height: 30px;
  background-color: #eee;
  width: 50%;
  padding: 3px 5px;
}

.animate {
  -webkit-transition: height linear 0.5s;
  transition: height linear 0.5s;
  overflow: hidden;
}
<script src="https://code.angularjs.org/1.3.15/angular.js"></script>
<script src="https://code.angularjs.org/1.3.15/angular-animate.js"></script>

<div class="container" ng-app="demo.app" ng-controller="MainCtrl">
  <h1 class="h3">Expandable Menu Demo</h1>
  <div ng-repeat="item in main">
    <div class="maincat" ng-click="active($index)">
      <p>{{item.title}}</p>
    </div>
    <div class="animate" ng-style="{height: item.active ? item.sub.length*30+'px' : '0px'}">
      <div ng-repeat="subitem in item.sub" class="subcat">
        <p>{{subitem.title}}</p>
      </div>
    </div>
  </div>
</div>

Upvotes: 2

MarcinPraski
MarcinPraski

Reputation: 24

CSS transitions require a property that the effect is going to be applied to declared. In order to specify, that the transition refers to height property you should change your code to:

transition: height 200ms cubic-bezier(0.4, 0, 1, 1);

Upvotes: 0

Related Questions