Skip to content
Matthew Adams By Matthew Adams Co-Founder
Angular.JS ngRepeat and Bootstrap layout bug on IE7

We have an Angular.JS application which is also using Bootstrap for its layout, and we've come across an irritating layout bug on IE7 (for which the client still has a requirement - albeit with a "please upgrade your browser if you can" notice).

Supporting IE7 with any modern web framework is a bit of a pain.

Discover your Power BI Maturity Score by taking our FREE 5 minute quiz.

First, we made sure that we followed all of the Angular guidelines for using IE7.

We made sure we included HTML5 shim and JSON3, plus Respond for responsiveness, and *almost* everything was rendering correctly, except for a horizontal row of elements produced by an ngRepeat element, which were too wide for the space, and wrapped underneath one another.

Looking closely, we observed that the first element had some unnecessary left margin. This stems from an IE7 bug that has long been fixed in IE8 and above, relating to the :firstChild pseudo class.

When Angular injects the relevant elements into the DOM to fulfil your ngRepeat request, it also injects a comment, like this:

On all other browsers, this comment is ignored when it comes to the pseudo-class :firstChild. On IE7 it is not, so your first actual element does not match the selector, and the css is not applied.

Sadly, Bootstrap uses this selector to set the left margin on that element to 0, to ensure the layout fits correctly.

Programming C# 12 Book, by Ian Griffiths, published by O'Reilly Media, is now available to buy.

Fortunately, Angular comes to the rescue in the form of $index This gives us the zero-based index of the current iteration of the repeat. We can use this to add custom classes for our first and last elements.

<div ng-repeat="page in pages" ng-class="getPageClass($index)">
// Do our stuff...
</div>

In our controller, getPageClass($index) builds the class list, adding our custom first and last classes when appropriate.

$scope.getPageClass = function($index) {
    var result = "span" + Math.max(1, Math.floor(12 / $scope.pageSize()));

    if ($index == 0) {
        result += " firstChildForIE7";
    }
    if ($index == $scope.pages.length - 1) {
        result += " lastChildForIE7";
    }
    return result;
};

And we can then target it with some custom styles.

.firstChildForIE7 {
    margin-left: 0 !important;    
}

.lastChildForIE7 {
    margin-right: 0 !important;    
} 

Matthew Adams

Co-Founder

Matthew Adams

Matthew was CTO of a venture-backed technology start-up in the UK & US for 10 years, and is now the co-founder of endjin, which provides technology strategy, experience and development services to its customers who are seeking to take advantage of Microsoft Azure and the Cloud.