How to Style a Flutter Bottom Navigation Bar for a Modern Look Without External Packages

You can achieve a modern Flutter bottom navigation bar aesthetic using the built-in BottomNavigationBarThemeData for global defaults combined with widget-specific properties like selectedIconTheme, elevation, and type, eliminating the need for external packages.

To style a Flutter bottom navigation bar with contemporary design patterns, leverage the framework's theme-driven architecture and constructor parameters. The Flutter SDK maintains this widget in the material package, providing deep customization through layered styling systems. This approach allows you to implement animated background colors, responsive icon scaling, and floating card-like appearances using only core framework capabilities.

Understanding the Styling Architecture

The visual appearance of BottomNavigationBar derives from three integrated layers in the Flutter SDK. According to the source code in packages/flutter/lib/src/material/bottom_navigation_bar.dart, the widget resolves its final appearance through a priority-based system.

Widget Properties

Direct constructor parameters provide the highest priority styling values. Properties like backgroundColor, selectedItemColor, unselectedItemColor, and type override theme defaults when explicitly provided. In the BottomNavigationBar constructor located in bottom_navigation_bar.dart, these values initialize the widget's internal state before any theme resolution occurs.

BottomNavigationBarThemeData Fallback

When widget properties are null, the bar queries the nearest BottomNavigationBarTheme descendant. The BottomNavigationBarThemeData class, defined in packages/flutter/lib/src/material/bottom_navigation_bar_theme.dart, supplies default values for all visual attributes including label styles, icon themes, and landscape layout behaviors. This ensures consistent styling across multiple navigation bars without repetitive code.

Internal Tile Implementation

Each item renders through an internal _BottomNavigationTile class that mixes resolved colors with animation curves. The _createTiles method in bottom_navigation_bar.dart constructs these tiles by combining effective icon themes (effectiveSelectedIconTheme, effectiveUnselectedIconTheme) with label styles. The _Label widget handles text styling and visibility, checking parameters like showUnselectedLabels to determine rendering behavior.

Modern Styling Techniques

Achieving specific modern UI patterns requires targeting the correct properties in the theme or widget constructor.

Animated Background Colors with Shifting Type

Set type: BottomNavigationBarType.shifting to enable per-item background color animations. When using this type, assign backgroundColor to each BottomNavigationBarItem—the selected item's background animates across the bar during transitions. The _effectiveType getter in the source code determines whether to use fixed or shifting behavior based on the provided type parameter and item count.

Custom Icon Themes and Label Styles

Control icon dimensions through selectedIconTheme and unselectedIconTheme properties. For typography, configure selectedLabelStyle with increased fontSize and fontWeight to create bold selected states. The internal _Label widget applies these styles and can animate font size changes via Transform widgets when values differ between selected and unselected states.

Floating and Elevated Designs

Create elevated card-like appearances using the elevation property (e.g., 8.0) combined with rounded corners. Wrap BottomNavigationBar in a ClipRRect widget with BorderRadius.vertical(top: Radius.circular(16)) to achieve the modern "pill" or floating bar aesthetic. The _Bar private widget class applies the elevation parameter to generate shadow effects.

Material 3 NavigationBar Alternative

For applications targeting Material Design 3, switch to the NavigationBar widget instead of BottomNavigationBar. Located in the same material package and referenced in comments within bottom_navigation_bar.dart, this newer widget implements the Material-3 specification with built-in modern styling including adaptive layouts and updated color schemes.

Implementation Examples

Global Theme Configuration

Configure BottomNavigationBarThemeData in your ThemeData to apply modern styling across all navigation bars automatically:

final ThemeData appTheme = ThemeData(
  useMaterial3: true,
  bottomNavigationBarTheme: const BottomNavigationBarThemeData(
    backgroundColor: Colors.white,
    elevation: 8,
    selectedItemColor: Colors.deepPurple,
    unselectedItemColor: Colors.grey,
    selectedIconTheme: IconThemeData(size: 30),
    unselectedIconTheme: IconThemeData(size: 24),
    selectedLabelStyle: TextStyle(
      fontWeight: FontWeight.bold,
      fontSize: 14,
    ),
    showUnselectedLabels: false,
    type: BottomNavigationBarType.shifting,
    landscapeLayout: BottomNavigationBarLandscapeLayout.centered,
  ),
);

MaterialApp(
  theme: appTheme,
  home: const MyHomePage(),
);

Per-Screen Implementation

Instantiate the bar with minimal code when using global theming:

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _selectedIndex = 0;
  static const List<Widget> _pages = <Widget>[
    Center(child: Text('Home')),
    Center(child: Text('Search')),
    Center(child: Text('Profile')),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _pages[_selectedIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedIndex,
        onTap: (index) => setState(() => _selectedIndex = index),
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
            backgroundColor: Colors.deepPurple,
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            label: 'Search',
            backgroundColor: Colors.indigo,
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: 'Profile',
            backgroundColor: Colors.teal,
          ),
        ],
      ),
    );
  }
}

Rounded Floating Bar Implementation

Achieve a floating card appearance using clipping and elevation:

class RoundedBottomNav extends StatelessWidget {
  const RoundedBottomNav({super.key});

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: const BorderRadius.vertical(top: Radius.circular(16)),
      child: BottomNavigationBar(
        elevation: 12,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
          BottomNavigationBarItem(icon: Icon(Icons.favorite), label: 'Likes'),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
        ],
      ),
    );
  }
}

Key Source Files

Understanding these implementations requires referencing specific files in the flutter/flutter repository:

  • packages/flutter/lib/src/material/bottom_navigation_bar.dart – Contains the core widget implementation, _BottomNavigationTile class, _createTiles method, and property resolution logic.
  • packages/flutter/lib/src/material/bottom_navigation_bar_theme.dart – Defines BottomNavigationBarThemeData and theme inheritance mechanisms.
  • packages/flutter/lib/src/widgets/bottom_navigation_bar_item.dart – Specifies the BottomNavigationBarItem data class for per-item configuration.

Summary

  • Style flutter bottom navigation bar using BottomNavigationBarThemeData for global defaults or constructor parameters for local overrides.
  • Use BottomNavigationBarType.shifting with per-item backgroundColor values to create animated color transitions.
  • Implement floating designs by wrapping the bar in ClipRRect and setting elevation values above 8.0.
  • Configure selectedIconTheme and selectedLabelStyle to emphasize the active navigation state.
  • Consider migrating to the NavigationBar widget for native Material 3 styling without external dependencies.
  • All styling capabilities reside in the core material package at packages/flutter/lib/src/material/bottom_navigation_bar.dart.

Frequently Asked Questions

How do I change the background color of only the selected item in Flutter's BottomNavigationBar?

Set the type property to BottomNavigationBarType.shifting and assign distinct backgroundColor values to each BottomNavigationBarItem. The framework animates the selected item's background color across the bar using the internal tile rendering logic in _createTiles.

What is the difference between BottomNavigationBar and NavigationBar in Flutter?

BottomNavigationBar is the legacy widget supporting Material 2 designs with extensive customization options, while NavigationBar implements the Material 3 specification with updated visual layouts and adaptive behaviors. Both reside in the core SDK and require no external packages.

How can I hide unselected labels while keeping selected labels visible?

Set showUnselectedLabels: false in your BottomNavigationBarThemeData or directly on the widget. This property controls the _Label widget's visibility logic, automatically fading unselected labels while maintaining selected label prominence.

Why are my icon colors not changing when I set selectedItemColor?

Ensure you are not overriding colors in the BottomNavigationBarItem icon widgets themselves. The selectedItemColor applies to icons only when they use default Icon widgets without explicit color parameters, as the theme resolution prioritizes widget-specific properties over inherited themes.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →