Question

Conditionally Apply a CSS Class in AngularJS

cssangularjs

Question

You have an array rendered inside a ul, with one li for each element, and a controller property called selectedIndex. How can you add a CSS class only to the li whose index matches selectedIndex in AngularJS?

For example, instead of manually duplicating the li markup, adding a class to one copy, and using ng-show / ng-hide to display only one version per index, what is the recommended AngularJS approach?

A simplified version might look like this:

<ul>
  <li ng-repeat="item in items">
    {{ item.name }}
  </li>
</ul>

And in the controller:

$scope.selectedIndex = 2;

Short Answer

By the end of this page, you will understand how AngularJS conditionally applies CSS classes using ngClass, especially when rendering lists with ngRepeat. You will also see how $index works, how to compare it with selectedIndex, and why this is better than duplicating HTML with ng-show and ng-hide.

Concept

In AngularJS, the standard way to conditionally apply a CSS class is with the ngClass directive.

When you render a list using ngRepeat, AngularJS gives you access to a special local variable called $index, which represents the current item's position in the loop. If your controller stores a selectedIndex, you can compare $index to that value and apply a class when they match.

This matters because:

  • It keeps your template small and readable.
  • It avoids duplicated markup.
  • It separates structure from styling.
  • It makes updates easier when selection changes.

Instead of rendering two versions of the same li, you render one li and let AngularJS decide whether it should include a class.

This is a common UI pattern in real applications:

  • selected menu items
  • active tabs
  • highlighted search results
  • chosen rows in a table
  • current step in a wizard

In short, ngClass is the AngularJS tool for dynamic styling based on application state.

Mental Model

Think of each li as a student in a line, and selectedIndex as the number of the student who should wear a badge.

You do not create two copies of every student—one with a badge and one without. Instead, you keep one student and simply ask:

  • “Is this the selected one?”
  • If yes, give them the badge.
  • If no, do nothing.

In AngularJS, ngRepeat gives each item a number ($index), and ngClass decides whether that item gets the CSS "badge" class.

Take Quiz

Syntax and Examples

The most common syntax is:

<li ng-repeat="item in items"
    ng-class="{ selected: $index === selectedIndex }">
  {{ item.name }}
</li>

Example

<ul>
  <li ng-repeat="item in items"
      ng-class="{ selected: $index === selectedIndex }">
    {{ item.name }}
  </li>
</ul>
$scope.items = [
  { name: 'Apple' },
  { name: 'Banana' },
  { name: 'Cherry' }
];

$scope.selectedIndex = 1;
.selected {
  background-color: #dbeafe;
  font-weight: bold;
}

What this does

  • ng-repeat="item in items" loops over the array.
  • $index is the current item's index: 0, 1, 2, and so on.
  • ng-class="{ selected: $index === selectedIndex }" adds the selected class only when the condition is true.

So if selectedIndex is 1, the second li gets the selected class.

Alternative syntax

AngularJS also supports other ngClass forms.

String form

<li ng-repeat="item in items"
    ng-class="$index === selectedIndex ? 'selected' : ''">
  {{ item.name }}
</li>

Multiple classes with object syntax

<li ng-repeat="item in items"
    ng-class="{
      selected: $index === selectedIndex,
      evenRow: $index % 2 === 0
    }">
  {{ item.name }}
</li>

The object form is usually the clearest for conditional classes.

Step by Step Execution

Consider this example:

<ul>
  <li ng-repeat="item in items"
      ng-class="{ selected: $index === selectedIndex }">
    {{ item.name }}
  </li>
</ul>
$scope.items = [
  { name: 'A' },
  { name: 'B' },
  { name: 'C' }
];

$scope.selectedIndex = 2;

Step-by-step

  1. AngularJS reads items and starts ngRepeat.
  2. For the first item:
    • item.name is A
    • $index is 0
    • condition is 0 === 2, which is false
    • no selected class is added
  3. For the second item:
    • item.name is B
    • $index is 1
    • condition is 1 === 2, which is false
    • no selected class is added
  4. For the third item:
    • item.name is C
    • $index is 2
    • condition is 2 === 2, which is true
    • AngularJS adds the selected class

Final rendered result

It behaves like this:

<ul>
  <li>A</li>
  <li>B</li>
  <li class="selected">C</li>
</ul>

If selectedIndex later changes to 0, AngularJS updates the classes automatically during digest processing, and the first item becomes selected instead.

Real World Use Cases

Conditional classes are used everywhere in AngularJS interfaces.

Navigation menus

Highlight the current menu item:

<li ng-repeat="link in links"
    ng-class="{ active: $index === selectedIndex }">
  {{ link.label }}
</li>

Tabs

Mark the open tab:

<button ng-repeat="tab in tabs"
        ng-class="{ activeTab: $index === selectedIndex }">
  {{ tab.title }}
</button>

Search results

Emphasize the currently focused result for keyboard navigation.

Data tables

Highlight the selected row in an admin dashboard.

Image galleries

Apply a border to the currently selected thumbnail.

Forms and validation

Add classes like error, valid, or dirty based on state.

In all of these cases, the idea is the same: the class reflects data or UI state.

Take Quiz

Real Codebase Usage

In real AngularJS projects, developers commonly use ngClass with simple conditions and keep the selection state in the controller.

Common pattern: selected index

<li ng-repeat="item in items"
    ng-class="{ selected: $index === selectedIndex }"
    ng-click="selectedIndex = $index">
  {{ item.name }}
</li>

This is a standard pattern for clickable lists.

Guarding against invalid values

Developers often make sure selectedIndex is valid before using it.

if ($scope.selectedIndex < 0 || $scope.selectedIndex >= $scope.items.length) {
  $scope.selectedIndex = 0;
}

Using item identity instead of index

In larger codebases, developers sometimes track the selected item by ID instead of index, because indexes can change if the list is filtered, sorted, or reordered.

<li ng-repeat="item in items"
    ng-class="{ selected: item.id === selectedItemId }">
  {{ item.name }}
</li>

Pairing with event handlers

<li ng-repeat="item in items"
    ng-class="{ selected: $index === selectedIndex }"
    ng-mouseenter="selectedIndex = $index">
  {{ item.name }}
</li>

Keeping templates clean

If the condition becomes too long, teams sometimes move logic into a controller method:

<li ng-repeat="item in items" ng-class="{ selected: isSelected($index) }">
  {{ item.name }}
</li>
$scope.isSelected = function(index) {
  return index === $scope.selectedIndex;
};

This should stay simple. If the logic is trivial, inline conditions are usually easier to read.

Common Mistakes

Here are common beginner mistakes when conditionally applying classes in AngularJS.

1. Duplicating markup with ng-show and ng-hide

Not recommended

<li ng-repeat="item in items" ng-show="$index === selectedIndex" class="selected">
  {{ item.name }}
</li>
<li ng-repeat="item in items" ng-hide="$index === selectedIndex">
  {{ item.name }}
</li>

This creates unnecessary duplication and makes templates harder to maintain.

Better

<li ng-repeat="item in items"
    ng-class="{ selected: $index === selectedIndex }">
  {{ item.name }}
</li>

2. Using class for dynamic logic

Broken approach:

<li class="$index === selectedIndex ? 'selected' : ''">
  {{ item.name }}
</li>

AngularJS does not evaluate expressions inside the normal class attribute like that.

Use ngClass instead.

3. Confusing = with comparison

Broken code:

<li ng-class="{ selected: $index = selectedIndex }">
  {{ item.name }}
</li>

Use comparison:

<li ng-class="{ selected: $index === selectedIndex }">
  {{ item.name }}
</li>

4. Forgetting that $index comes from ngRepeat

$index only exists inside the ng-repeat scope.

Broken example:

<p ng-class="{ selected: $index === selectedIndex }">Hello</p>

This will not work unless the element is inside an ngRepeat block.

5. Depending on index when list order can change

If items are sorted or filtered, the selected index may no longer point to the same item.

Safer option:

<li ng-repeat="item in items"
    ng-class="{ selected: item.id === selectedItemId }">
  {{ item.name }}
</li>

6. Forgetting to define the CSS class

Even if AngularJS adds the class, nothing visible happens unless your CSS exists.

.selected {
  background: yellow;
}

Comparisons

Here is how ngClass compares with related AngularJS approaches.

ApproachBest forGood choice here?Notes
ng-classConditionally adding/removing CSS classesYesClean, readable, standard solution
classStatic classes onlyNoDoes not handle AngularJS conditional logic by itself
ng-show / ng-hideShowing or hiding entire elementsNoChanges visibility, not styling
ng-styleDynamic inline stylesSometimesUseful for one-off styles, but classes are usually cleaner
ng-ifCreating/removing elements from the DOMNoToo heavy if you only need a class

ngClass vs ngStyle

<li ng-class="{ selected: $index === selectedIndex }">

vs.

<li ng-style="{ 'font-weight': $index === selectedIndex ? 'bold' : 'normal' }">

Use ngClass when:

  • styling belongs in CSS
  • multiple style rules are involved
  • you want cleaner templates

Use ngStyle when:

  • you need a small dynamic inline style
  • the value is highly variable, such as width or color from data

Index-based selection vs ID-based selection

TechniqueAdvantageDrawback
selectedIndexSimple and easy for small listsCan break if list order changes
selectedItemIdMore stable in real appsRequires each item to have an ID

For a beginner example, selectedIndex is perfect. In larger apps, IDs are often safer.

Take Quiz

Cheat Sheet

<li ng-repeat="item in items"
    ng-class="{ selected: $index === selectedIndex }">
  {{ item.name }}
</li>

Key points

  • Use ngClass for conditional CSS classes.
  • Use $index inside ngRepeat.
  • Compare $index with selectedIndex.
  • Prefer object syntax for readability.

Common forms

Object syntax

ng-class="{ selected: $index === selectedIndex }"

Ternary syntax

ng-class="$index === selectedIndex ? 'selected' : ''"

Multiple classes

ng-class="{ selected: isSelected, disabled: isDisabled }"

Rules

  • $index exists only inside ngRepeat.
  • ng-show / ng-hide are for visibility, not for styling.
  • Define the CSS class in your stylesheet.
  • Use === for comparison.

Safer alternative for changing lists

<li ng-repeat="item in items"
    ng-class="{ selected: item.id === selectedItemId }">
  {{ item.name }}
</li>

FAQ

How do I add a class to one item in an AngularJS ngRepeat?

Use ng-class and compare $index with your selected value.

<li ng-repeat="item in items" ng-class="{ selected: $index === selectedIndex }">

Is ngClass better than ng-show and ng-hide for this?

Yes. ngClass is the correct tool when you want to style an element differently. ng-show and ng-hide are for visibility, not class changes.

What is $index in AngularJS?

$index is a local variable available inside ngRepeat. It contains the current loop position starting from 0.

Can I use a class name string instead of object syntax in ngClass?

Yes.

ng-class="$index === selectedIndex ? 'selected' : ''"

But object syntax is often easier to read and extend.

Why is my class not appearing visually?

Possible reasons:

  • the condition is false
  • the CSS class is not defined
  • selectedIndex has the wrong value
  • the element is not inside ngRepeat, so $index is unavailable

Should I use index or item ID for selection?

For simple lists, index is fine. For lists that can be sorted, filtered, or reordered, using an item ID is usually safer.

Can I change the selected item when the user clicks?

Yes.

<li ng-repeat="item in items"
    ng-class="{ selected: $index === selectedIndex }"
    ng-click="selectedIndex = $index">
  {{ item.name }}
</li>
Take Quiz

Mini Project

Description

Build a selectable list of items in AngularJS. The user should be able to click any item in the list, and the clicked item should receive a highlight class. This project demonstrates how ngRepeat, $index, ngClick, and ngClass work together in a practical UI pattern.

Goal

Create an AngularJS list where exactly one item is highlighted based on selectedIndex, and clicking an item changes the selection.

Requirements

  • Render a list of items using ngRepeat.
  • Store the selected item position in selectedIndex.
  • Apply a CSS class only when $index === selectedIndex.
  • Update selectedIndex when a user clicks an item.
  • Add visible CSS so the selected item is clearly highlighted.
Take Quiz

Keep learning

Related questions

View more