How to Format your React App for Mobile
Styling tips to make your app work for any screen size
These days, it's increasingly common for employers to review applications on their mobile devices. Ensuring your application works seamlessly across various screen sizes is essential.
Fortunately, React, JavaScript, and CSS offer a range of tools that make adapting to different devices straightforward.
This article will explore the following methods that can be used to effectively implement these solutions:
Take advantage of conditional rendering
Use styled components with props
Use media queries in CSS/styled components
Use clamp for sizing
Set max values values based on viewport
Use grid-template-columns for repeated elements
How will my components know if I’m using a Mobile Device?
» Use a React Context Provider to determine if the screen width is below a certain threshold
Step 1: Create a Provider with createContext
. The window width context below looks at the current window size and returns true if the screen has a width below 768.
import React, { createContext, useContext, useState, useEffect } from 'react';
const WindowWidthContext = createContext();
const WindowWidthProvider = ({ children }) => {
const [isMobile, setIsMobile] = useState(window.innerWidth <= 768);
useEffect(() => {
const handleResize = () => setIsMobile(window.innerWidth <= 768);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
// Pass an object with isMobile to match usage
return (
<WindowWidthContext.Provider value={{ isMobile }}>
{children}
</WindowWidthContext.Provider>
);
};
export { WindowWidthProvider, WindowWidthContext };
Step 2: Wrap your main content in the provider to create context for all your routes
import React, { StrictMode } from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { createHashRouter, RouterProvider } from 'react-router-dom'; // Import HashRouter
import routes from './routes'; // Import your routes configuration
import { WindowWidthProvider } from './context/windowSize';
// Create the hash-based router
const router = createHashRouter(routes);
// Create the root and render the app with the router
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<StrictMode>
<WindowWidthProvider>
<RouterProvider router={router} />
</WindowWidthProvider>
</StrictMode>,
);
Step 3: Use the newly created context in your component to find whether or not the current window is smaller than the pre-defined threshold. We can then store this boolean value as ‘isMobile’ in any components to use for conditional rendering and/or conditional CSS rules (described in the next sections).
import React, {useContext} from 'react';
import NavBar from "./NavBar"
import MobileNavBar from './MobileNavBar';
import {WindowWidthContext} from "../context/windowSize";
const Header = () => {
const { isMobile } = useContext(WindowWidthContext);
..
Using this setup, the value of isMobile will re-calculate every time the screen size changes. That way, if you reduce the viewport width of the application on your computer past the threshold, the site will switch to the mobile view automatically.
Tip #1: Take advantage of conditional rendering
In some cases no matter how much you tweak the styling rules, a certain component of your application just won’t work well for smaller screens. In these situations, conditional rendering in React can help to either switch out a component for another, or hide it completely.
One common example of this is a navigation pane. On larger screens, navigation bars often show all the tabs separately across the page, whereas mobile versions of the same site will have a ‘hamburger menu’ that drops down. This functionality can be achieved by rendering the appropriate component based on the window size, as shown in the example below.
...
import {WindowWidthContext} from "../context/windowSize";
const Header = () => {
const { isMobile } = useContext(WindowWidthContext);
return (
<header>
{isMobile ? <MobileNavBar /> : <NavBar />}
</header>
);
}
export default Header;
Alternatively, you can limit mobile functionality by rendering certain components only if the screen size is large enough. One example where this may be used is a sidebar that would otherwise take up too much room on a narrow window.
{!isMobile &&
<SideBar
filterInput={filterInput}
setFilterInput={setFilterInput}
/>
}
Tip #2: Use styled components with props
Props inside styled components are another great way to adjust styling for different screen sizes. You can use this method to apply a certain style based on the window size. In the example below, props are used to apply a margin only for larger screens.
const StyledMain = styled.main`
.main-content {
margin: ${(props) => props.isMobile ? '0px' : '20px'};
}
`;
Tip #3: Use media queries in CSS/styled components
Media queries in CSS will also allow you to set styling rules based on the size of the screen. The example below sets the flex direction to row for larger screens so that elements are shown side by side, but switches to column for smaller screens to show those same elements top to bottom.
const StyledArticle = styled.article`
display: flex;
flex-direction: row;
@media screen and (max-width: 768px) {
flex-direction: column;
}
`;
Tip #4: Use clamp for sizing
In CSS, you can use clamp
for setting minimum, default, and maximum sizes. In the example below, this function is used to set the default font sizes in the application. This helps to make sure the font does not become too small for mobile screen or too large for very large screens. This ensures readability across all devices.
:root {
--default-font-size: clamp(0.7rem, 1.7vw, .9rem);
}
h1 {
font-size: clamp(1.4rem, 3.5vw, 2rem);
}
h2 {
font-size: clamp(1rem, 3vw, 1.5rem);
}
h3 {
font-size: clamp(.9rem, 2vw, 1.25rem);
}
p, label, i, li, a {
font-size: var(--default-font-size)
}
Tip #5: Set max values based on viewport
Applying minimum, default, and maximum widths to components is a simple way to enhance your app's visual appeal across different screen sizes. By using relative units like viewport width (vw
) or percentages (%
) instead of fixed units like pixels (px
), you can ensure that components adapt fluidly and do not extend beyond the screen boundaries.
const StyledForm = styled.form`
width: 700px;
min-width: 40vw;
max-width: 90vw;
`
Tip #6: Use grid-template-columns for repeated elements
Formats like grid-template-columns
with auto-fit
enable your app to automatically adjust the size and layout of elements based on the specified minimum and maximum widths. The example below demonstrates how this setting can dynamically adjust the number of columns or rows in a container based on these parameters.
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
Conclusion
An attractive, responsive design improves user experience and leaves a strong impression on potential employers. These are just a handful of ways to get your application to be visually appealing for different screen sizes.
When building out your app, make sure to test it out on as many screen sizes as possible!
While visual optimization is a good first step for building out your mobile app, it is also essential to consider the technical performance when you need to scale your application. For advice on improving performance in your mobile application, check out:
https://uxcam.com/blog/how-to-improve-mobile-app-performance/