Expo Router bottom tabs styling not working as expected #173886
Replies: 4 comments 1 reply
|
To create a floating, rounded bottom tab bar with centered icons and a focused tab with a larger width in your Expo project using Expo Router, you'll need to customize the tab bar styles appropriately. Here’s a step-by-step guide to achieve your goal: 1. Install Expo Router and DependenciesMake sure you have Expo Router set up. If you haven’t done so already, you can follow the official Expo guide to install it. 2. Setting Up Bottom Tab NavigationIf you haven't set up the bottom tab navigator yet, here's how you can set it up with First, install the necessary libraries: expo install @react-navigation/native @react-navigation/bottom-tabs react-native-screens react-native-safe-area-contextThen, create a basic bottom tab navigator structure: import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { NavigationContainer } from '@react-navigation/native';
import HomeScreen from './screens/Home';
import SettingsScreen from './screens/Settings';
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={{
tabBarStyle: {
position: 'absolute',
bottom: 20,
left: 20,
right: 20,
borderRadius: 30,
height: 70, // adjust based on preference
backgroundColor: '#ffffff', // tab bar background
elevation: 10, // for Android shadow
},
tabBarIconStyle: {
width: 24, // adjust icon size
height: 24, // adjust icon size
},
}}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}3. Styling the Floating Tab BarNow, let's add some custom styles for the floating and rounded tab bar. The key things to focus on are:
You’ll achieve this by applying custom styles to the Key Points:
4. Implementation ExampleHere’s how you can center the icons and apply the focused styling: import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { NavigationContainer } from '@react-navigation/native';
import { View } from 'react-native';
import Ionicons from 'react-native-vector-icons/Ionicons'; // or any icon library of your choice
import HomeScreen from './screens/Home';
import SettingsScreen from './screens/Settings';
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarStyle: {
position: 'absolute',
bottom: 20,
left: 20,
right: 20,
borderRadius: 30,
height: 70, // Adjust the height
backgroundColor: '#ffffff',
elevation: 10,
shadowColor: '#000000', // Shadow for iOS
shadowOffset: { width: 0, height: 10 },
shadowOpacity: 0.25,
shadowRadius: 5,
},
tabBarIcon: ({ focused }) => {
const iconName =
route.name === 'Home' ? 'home' : 'settings'; // Change based on route
return (
<Ionicons
name={iconName}
size={focused ? 32 : 24} // Larger size for focused tab
color={focused ? '#007bff' : '#444'}
style={{
marginBottom: focused ? 0 : 5, // Adjust margin to keep centered
}}
/>
);
},
tabBarIconStyle: {
alignItems: 'center',
justifyContent: 'center',
},
tabBarLabelStyle: {
display: 'none', // Hides label, if you just want icons
},
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}5. Key Adjustments in the Code
6. Additional CustomizationsIf you want more control, you can adjust these properties further:
7. Troubleshooting Tips
ConclusionWith these changes, you should now have a floating, rounded bottom tab bar with centered icons, and the focused tab will have a larger width and icon size. Let me know if you need any more adjustments or run into any specific issues! |
|
I’d use a custom bottom tab bar component instead of styling the default one. React Navigation docs: function MyTabs() {
return (
<Tab.Navigator
tabBar={(props) => <MyTabBar {...props} />}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>
);
} |
Why this happens
What to do (copy-paste ready)
Below is a full working example you can paste into your import React, { useRef, useEffect } from "react";
import { Tabs } from "expo-router";
import {
View,
TouchableOpacity,
Animated,
Platform,
SafeAreaView,
StyleSheet,
} from "react-native";
import { HugeiconsIcon } from "@hugeicons/react-native";
import { Home09Icon, Wallet01Icon, Analytics01Icon, Settings01Icon } from "@hugeicons/core-free-icons";
// --- Custom tab button ---
function TabButton({ children, onPress, accessibilityState }) {
const focused = accessibilityState?.selected ?? false;
const anim = useRef(new Animated.Value(focused ? 1 : 0)).current;
useEffect(() => {
Animated.timing(anim, {
toValue: focused ? 1 : 0,
duration: 180,
useNativeDriver: false,
}).start();
}, [focused, anim]);
// interpolate width (base 54 -> focused 90)
const width = anim.interpolate({
inputRange: [0, 1],
outputRange: [54, 90],
});
return (
<TouchableOpacity activeOpacity={0.85} onPress={onPress} style={styles.tabButtonTouchable}>
<Animated.View style={[styles.tabButton, { width }]}>
<View style={styles.iconWrapper}>{children}</View>
</Animated.View>
</TouchableOpacity>
);
}
// --- Tab layout ---
export default function TabLayout() {
return (
<SafeAreaView style={{ flex: 1 }}>
<Tabs
screenOptions={{
headerShown: false,
tabBarShowLabel: false,
tabBarStyle: styles.tabBar,
tabBarActiveTintColor: "#0b84ff",
tabBarInactiveTintColor: "#8a8a8a",
}}
>
<Tabs.Screen
name="index"
options={{
tabBarButton: (props) => <TabButton {...props} />,
tabBarIcon: ({ color, focused }) => (
<HugeiconsIcon icon={Home09Icon} color={color} strokeWidth={1.8} fill={focused ? color : "none"} />
),
}}
/>
<Tabs.Screen
name="wallet"
options={{
tabBarButton: (props) => <TabButton {...props} />,
tabBarIcon: ({ color }) => <HugeiconsIcon icon={Wallet01Icon} color={color} strokeWidth={1.8} />,
}}
/>
<Tabs.Screen
name="statistics"
options={{
tabBarButton: (props) => <TabButton {...props} />,
tabBarIcon: ({ color }) => <HugeiconsIcon icon={Analytics01Icon} color={color} strokeWidth={1.8} />,
}}
/>
<Tabs.Screen
name="settings"
options={{
tabBarButton: (props) => <TabButton {...props} />,
tabBarIcon: ({ color }) => <HugeiconsIcon icon={Settings01Icon} color={color} strokeWidth={1.8} />,
}}
/>
</Tabs>
</SafeAreaView>
);
}
// --- Styles ---
const styles = StyleSheet.create({
tabBar: {
position: "absolute",
left: "5%",
right: "5%",
bottom: Platform.OS === "android" ? 18 : 25,
height: 75,
borderRadius: 40,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
elevation: 6,
shadowColor: "#000",
shadowOpacity: 0.08,
shadowRadius: 12,
shadowOffset: { width: 0, height: 8 },
// remove paddingTop which can push content up
paddingHorizontal: 8,
},
tabButtonTouchable: {
// touchable wrapper — no extra styling required
},
tabButton: {
height: 54, // button height
borderRadius: 30,
backgroundColor: "transparent", // change on focus if you want
alignItems: "center",
justifyContent: "center",
marginHorizontal: 6,
},
iconWrapper: {
// ensure the icon is centered inside the button
alignItems: "center",
justifyContent: "center",
// do NOT use 'height: "100%"' here; keep fixed sizing consistent
width: "100%",
},
});Extra tips & gotchas
|
|
Tailwind CSS background colors are applied using utility classes like bg-blue-500, bg-gray-100, or bg-black. They allow you to quickly style elements with consistent, responsive colors taken from Tailwind’s predefined palette or your custom theme. You can also use opacity modifiers, gradients, and CSS variables to create modern, flexible backgrounds without writing custom CSS. |
Uh oh!
There was an error while loading. Please reload this page.
Body
My goal is to create a floating, rounded bottom tab bar where icons are perfectly centered and the focused tab is styled differently (larger width).
I’m working on an Expo project using Expo Router and trying to style my bottom tabs. But the CSS isn’t behaving as expected.
Like, i want the tab items to be centered but they looks slighly upward.
Not only this, i wanted to give focused tabitem a different width but that also doesn't seem to work as expected. I want to achieve this.


but getting this instead
Question:
👉 Why does this happen? Is there a better way to style bottom tabs in Expo Router so layout/positioning works as intended?
Environment
Guidelines
All reactions