Menu

Mastering MUI Divider: Building Section Dividers with Labels in React

As a front-end developer working with Material UI, you'll often need visual separators to organize your UI into logical sections. The MUI Divider component is a versatile tool that goes beyond simple horizontal lines. In this guide, I'll show you how to leverage the full potential of MUI Divider to create professional section dividers with labels, exploring various customization options and real-world implementations.

What You'll Learn

By the end of this article, you'll be able to:

  • Implement basic and advanced MUI Dividers in your React applications
  • Create section dividers with centered, inset, and custom-positioned labels
  • Style and customize dividers to match your design system
  • Handle responsive divider layouts
  • Integrate dividers with other MUI components for cohesive interfaces
  • Troubleshoot common divider implementation issues

Understanding the MUI Divider Component

The Divider component in Material UI provides a thin line that groups content in lists and layouts. While it may seem simple at first glance, it offers significant flexibility for creating visual separation with semantic meaning in your interfaces.

Basic Divider Implementation

At its core, the Divider component renders an <hr> element with styling that aligns with Material Design principles. Let's start with the most basic implementation:

import * as React from 'react';
import { Box, Divider } from '@mui/material';

function BasicDivider() {
return (
<Box sx={{ width: '100%', maxWidth: 500, bgcolor: 'background.paper' }}>
<Box sx={{ my: 2, px: 2 }}>Content above the divider</Box>
<Divider />
<Box sx={{ my: 2, px: 2 }}>Content below the divider</Box>
</Box>
);
}

This creates a simple horizontal line that spans the width of its container. The divider inherits its color from the theme's divider value by default, typically a light gray that provides subtle separation without being visually overwhelming.

Divider Variants and Orientations

MUI Divider supports both horizontal (default) and vertical orientations, allowing you to create boundaries in different directions based on your layout requirements.

import * as React from 'react';
import { Box, Divider } from '@mui/material';

function DividerVariants() {
return (
<Box sx={{ display: 'flex', alignItems: 'center', width: '100%', height: 100 }}>
<Box sx={{ p: 2 }}>Left content</Box>
{/* Vertical divider */}
<Divider orientation="vertical" flexItem />
<Box sx={{ p: 2 }}>Middle content</Box>
{/* Vertical divider with variant */}
<Divider orientation="vertical" variant="middle" flexItem />
<Box sx={{ p: 2 }}>Right content</Box>
</Box>
);
}

The orientation prop accepts either "horizontal" or "vertical" values. When using vertical dividers, the flexItem prop is particularly useful as it makes the divider take the height of its flex container.

Divider Props Deep Dive

Let's explore the comprehensive set of props available for the Divider component to understand its full capabilities.

PropTypeDefaultDescription
absolutebooleanfalse

If true, the divider will have an absolute position, useful when used in a list item.

childrennode-

The content of the component, typically used to add text within the divider.

classesobject-Override or extend the styles applied to the component.
componentelementType'hr' for horizontal, 'div' for verticalThe component used for the root node.
flexItembooleanfalse

If true, the divider will have flex item behavior, adapting to flex container.

lightbooleanfalseIf true, the divider will have a lighter color.
orientation'horizontal' | 'vertical''horizontal'The divider orientation.
textAlign'center' | 'left' | 'right''center'The text alignment when the divider has children.
variant'fullWidth' | 'inset' | 'middle''fullWidth'The variant to use.
sxobject | function-

The system prop that allows defining system overrides as well as additional CSS styles.

Understanding Divider Variants

The variant prop offers three options that affect the divider's width and positioning:

  1. fullWidth (default): The divider extends across the full width of its container
  2. inset: The divider is indented, starting with a margin from the left
  3. middle: The divider has margins on both left and right sides
import * as React from 'react';
import { Box, List, ListItem, ListItemText, Divider } from '@mui/material';

function DividerVariantDemo() {
return (
<List sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}>
<ListItem>
<ListItemText primary="Default fullWidth divider" />
</ListItem>
<Divider />

      <ListItem>
        <ListItemText primary="Inset divider" />
      </ListItem>
      <Divider variant="inset" />

      <ListItem>
        <ListItemText primary="Middle divider" />
      </ListItem>
      <Divider variant="middle" />

      <ListItem>
        <ListItemText primary="Last item" />
      </ListItem>
    </List>

);
}

The inset variant is particularly useful in list contexts when you want to align the divider with the text content, creating a more polished look by indenting the divider to match list item content.

Creating Dividers with Text Labels

One of the most powerful features of MUI Divider is the ability to include text labels within the divider itself. This is especially useful for section headers or to provide context between content blocks.

Basic Text Divider

Let's create a simple divider with centered text:

import * as React from 'react';
import { Box, Divider, Typography } from '@mui/material';

function TextDivider() {
return (
<Box sx={{ width: '100%', maxWidth: 500, my: 4 }}>
<Typography variant="body1" gutterBottom>
Content above the divider
</Typography>

      <Divider>SECTION</Divider>

      <Typography variant="body1" sx={{ mt: 2 }}>
        Content below the divider
      </Typography>
    </Box>

);
}

By default, the text is centered within the divider. The divider creates lines on both sides of the text, creating a clean and professional section header.

Controlling Text Alignment

You can control the text alignment using the textAlign prop, which accepts 'center', 'left', or 'right':

import * as React from 'react';
import { Box, Divider, Stack } from '@mui/material';

function AlignedTextDividers() {
return (
<Stack spacing={3} sx={{ width: '100%', maxWidth: 500 }}>
<Divider textAlign="left">Left Aligned</Divider>
<Divider textAlign="center">Center Aligned (Default)</Divider>
<Divider textAlign="right">Right Aligned</Divider>
</Stack>
);
}

This allows you to create visual hierarchies and align section headers with other content in your layout. Left-aligned divider text works well for forms or content with a left-aligned reading pattern, while right-aligned can be useful for RTL languages or special design cases.

Custom Content in Dividers

You're not limited to just text in dividers. You can include any React node, such as icons, badges, or custom components:

import * as React from 'react';
import { Box, Divider, Chip, Avatar } from '@mui/material';
import StarIcon from '@mui/icons-material/Star';

function CustomContentDivider() {
return (
<Box sx={{ width: '100%', maxWidth: 500, my: 4 }}>
{/* Divider with an icon */}
<Divider sx={{ mb: 4 }}>
<StarIcon color="primary" />
</Divider>

      {/* Divider with a chip */}
      <Divider sx={{ mb: 4 }}>
        <Chip
          label="FEATURED SECTION"
          color="primary"
          size="small"
        />
      </Divider>

      {/* Divider with an avatar */}
      <Divider>
        <Avatar
          alt="User Avatar"
          src="/static/images/avatar/1.jpg"
          sx={{ width: 24, height: 24 }}
        />
      </Divider>
    </Box>

);
}

This flexibility allows you to create highly customized section dividers that match your application's design language and provide additional context or visual interest.

Step-by-Step Guide: Building a Section Divider with Label

Let's build a complete example of a section divider with a label that you can use in your React applications. We'll start from the basics and progressively enhance the component.

Step 1: Set Up Your Project Environment

First, ensure you have the necessary dependencies installed:

npm install @mui/material @emotion/react @emotion/styled @mui/icons-material

If you're using yarn:

yarn add @mui/material @emotion/react @emotion/styled @mui/icons-material

These packages provide the core MUI components, styling solutions, and icons we'll use in our implementation.

Step 2: Create a Basic Section Divider Component

Let's start by creating a reusable section divider component that accepts a label:

import React from 'react';
import { Divider, Box } from '@mui/material';

function SectionDivider({ label, ...props }) {
return (
<Box sx={{ width: '100%', my: 2 }}>
<Divider {...props}>{label}</Divider>
</Box>
);
}

export default SectionDivider;

This component wraps the MUI Divider with some default spacing and allows passing a label as a prop. The spread operator (...props) enables passing any additional Divider props to customize the component further.

Step 3: Implement the Divider in a Layout

Now, let's use our SectionDivider component in a real layout:

import React from 'react';
import { 
  Box, 
  Typography, 
  Card, 
  CardContent,
  Container 
} from '@mui/material';
import SectionDivider from './SectionDivider';

function ProductPage() {
return (
<Container maxWidth="md">
<Typography variant="h4" component="h1" gutterBottom sx={{ mt: 4 }}>
Product Details
</Typography>

      <Card sx={{ mb: 4 }}>
        <CardContent>
          <Typography variant="body1">
            This is the product overview section with basic information.
          </Typography>
        </CardContent>
      </Card>

      <SectionDivider label="SPECIFICATIONS" />

      <Card sx={{ mb: 4 }}>
        <CardContent>
          <Typography variant="body1">
            Detailed product specifications and technical details.
          </Typography>
        </CardContent>
      </Card>

      <SectionDivider label="CUSTOMER REVIEWS" textAlign="left" />

      <Card>
        <CardContent>
          <Typography variant="body1">
            Reviews and ratings from verified customers.
          </Typography>
        </CardContent>
      </Card>
    </Container>

);
}

export default ProductPage;

In this example, we've created a product page layout with multiple sections, each separated by our custom SectionDivider component. We've also demonstrated how to customize the text alignment for different sections.

Step 4: Enhance the Divider with Custom Styling

Let's enhance our SectionDivider component with more customization options and better styling:

import React from 'react';
import { Divider, Box, Typography, useTheme } from '@mui/material';

function EnhancedSectionDivider({
label,
textAlign = 'center',
fontSize = 'subtitle2',
color,
dividerColor,
spacing = 2,
fontWeight = 'medium',
...props
}) {
const theme = useTheme();

// Determine colors with fallbacks
const textColor = color || theme.palette.text.secondary;
const lineColor = dividerColor || theme.palette.divider;

return (
<Box sx={{ width: '100%', my: spacing }}>
<Divider
textAlign={textAlign}
sx={{
          '&::before, &::after': {
            borderColor: lineColor,
          },
          '& .MuiDivider-wrapper': {
            paddingLeft: textAlign === 'left' ? 0 : undefined,
            paddingRight: textAlign === 'right' ? 0 : undefined,
          },
        }}
{...props} >
<Typography
variant={fontSize}
component="span"
sx={{
            color: textColor,
            fontWeight: fontWeight,
            letterSpacing: '0.5px',
          }} >
{label}
</Typography>
</Divider>
</Box>
);
}

export default EnhancedSectionDivider;

This enhanced version provides:

  • Custom text color and divider color options
  • Typography variant control for the label
  • Custom spacing around the divider
  • Font weight customization
  • Special handling for left and right alignment padding

Step 5: Use the Enhanced Divider in Different Contexts

Now let's implement our enhanced divider in different contexts to showcase its versatility:

import React from 'react';
import { 
  Box, 
  Container, 
  Typography, 
  Paper,
  List,
  ListItem,
  ListItemText,
  useTheme
} from '@mui/material';
import EnhancedSectionDivider from './EnhancedSectionDivider';

function DividerShowcase() {
const theme = useTheme();

return (
<Container maxWidth="md" sx={{ py: 4 }}>
<Typography variant="h4" gutterBottom>
Divider Showcase
</Typography>

      {/* Standard usage */}
      <EnhancedSectionDivider label="DEFAULT SECTION" />
      <Paper sx={{ p: 2, mb: 4 }}>
        <Typography>Standard section content</Typography>
      </Paper>

      {/* Custom colors */}
      <EnhancedSectionDivider
        label="IMPORTANT SECTION"
        color={theme.palette.primary.main}
        dividerColor={theme.palette.primary.light}
        fontWeight="bold"
      />
      <Paper sx={{ p: 2, mb: 4 }}>
        <Typography>Section with primary color theme</Typography>
      </Paper>

      {/* Left aligned with custom spacing */}
      <EnhancedSectionDivider
        label="LIST ITEMS"
        textAlign="left"
        spacing={3}
        fontSize="body2"
      />
      <List>
        {['Item 1', 'Item 2', 'Item 3'].map((item) => (
          <ListItem key={item} divider>
            <ListItemText primary={item} />
          </ListItem>
        ))}
      </List>

      {/* Right aligned for special cases */}
      <Box sx={{ mt: 4 }}>
        <EnhancedSectionDivider
          label="ADDITIONAL INFO"
          textAlign="right"
          color={theme.palette.text.disabled}
        />
        <Paper sx={{ p: 2 }}>
          <Typography variant="body2">
            Supplementary information with right-aligned header
          </Typography>
        </Paper>
      </Box>
    </Container>

);
}

export default DividerShowcase;

This showcase demonstrates different configurations of our enhanced divider component, highlighting its flexibility across various UI contexts.

Step 6: Create a Responsive Section Divider

For responsive designs, we might want our divider to adapt to different screen sizes. Let's enhance our component to handle this:

import React from 'react';
import { Divider, Box, Typography, useTheme, useMediaQuery } from '@mui/material';

function ResponsiveSectionDivider({
label,
textAlign = { xs: 'center', md: 'left' },
fontSize = { xs: 'body2', md: 'subtitle2' },
spacing = { xs: 1.5, md: 2.5 },
...props
}) {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));

// Convert string values to responsive objects if needed
const resolvedTextAlign = typeof textAlign === 'string'
? { xs: textAlign }
: textAlign;

const resolvedFontSize = typeof fontSize === 'string'
? { xs: fontSize }
: fontSize;

const resolvedSpacing = typeof spacing === 'number'
? { xs: spacing }
: spacing;

// Determine the effective text alignment for the current breakpoint
const effectiveTextAlign = isMobile
? resolvedTextAlign.xs || 'center'
: resolvedTextAlign.md || resolvedTextAlign.xs || 'left';

return (
<Box sx={{ width: '100%', my: resolvedSpacing }}>
<Divider
textAlign={effectiveTextAlign}
{...props} >
<Typography
variant={isMobile ? resolvedFontSize.xs : resolvedFontSize.md || resolvedFontSize.xs}
component="span"
sx={{
            fontWeight: isMobile ? 'regular' : 'medium',
            letterSpacing: isMobile ? '0.25px' : '0.5px',
          }} >
{label}
</Typography>
</Divider>
</Box>
);
}

export default ResponsiveSectionDivider;

This responsive version allows you to:

  • Define different text alignments for different breakpoints
  • Adjust the font size based on screen size
  • Change spacing around the divider for different devices
  • Apply different typographic styles based on viewport

Advanced Customization Techniques

Beyond the basic implementation, there are several ways to customize MUI dividers to perfectly match your design system.

Custom Styling with the sx Prop

The sx prop is the most direct way to apply custom styles to your divider:

import React from 'react';
import { Divider, Box } from '@mui/material';

function CustomStyledDividers() {
return (
<Box sx={{ width: '100%', maxWidth: 500 }}>
{/* Gradient divider */}
<Divider
sx={{
          my: 4,
          height: 3,
          backgroundImage: 'linear-gradient(to right, rgba(0,0,0,0), rgba(25,118,210,1), rgba(0,0,0,0))',
          border: 'none'
        }}
/>

      {/* Dotted divider */}
      <Divider
        sx={{
          my: 4,
          borderStyle: 'dotted',
          borderWidth: 2,
          borderColor: 'primary.light'
        }}
      />

      {/* Thick divider with rounded ends */}
      <Divider
        sx={{
          my: 4,
          height: 6,
          borderRadius: 3,
          bgcolor: 'secondary.main'
        }}
      />

      {/* Divider with shadow */}
      <Divider
        sx={{
          my: 4,
          height: 1,
          bgcolor: 'background.paper',
          boxShadow: '0 1px 2px rgba(0,0,0,0.2)'
        }}
      />
    </Box>

);
}

export default CustomStyledDividers;

These examples showcase various visual styles you can achieve with the sx prop, from gradients to shadows to custom border styles.

Theme Customization

For consistent styling across your application, you can customize the Divider component through the theme:

import { createTheme, ThemeProvider } from '@mui/material/styles';
import { CssBaseline, Box, Divider } from '@mui/material';

// Create a custom theme with divider overrides
const theme = createTheme({
components: {
MuiDivider: {
styleOverrides: {
// Apply to all dividers
root: {
borderColor: '#e0e0e0',
'&::before, &::after': {
borderColor: '#e0e0e0',
},
},
// Apply to dividers with text
withChildren: {
'&::before, &::after': {
borderWidth: '1px',
},
'& .MuiDivider-wrapper': {
padding: '0 16px',
},
},
// Apply to dividers with textAlign="left"
textAlignLeft: {
'&::before': {
width: '5%',
},
},
// Apply to middle variant
middle: {
marginLeft: 24,
marginRight: 24,
},
},
// Default props for all dividers
defaultProps: {
light: true, // Use lighter color by default
},
},
},
});

function ThemedDividers() {
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Box sx={{ p: 3 }}>
<Divider>Themed Divider</Divider>
<Box sx={{ my: 2 }} />
<Divider textAlign="left">Left Aligned</Divider>
<Box sx={{ my: 2 }} />
<Divider variant="middle">Middle Variant</Divider>
</Box>
</ThemeProvider>
);
}

export default ThemedDividers;

Theme customization ensures consistent styling across your application and reduces the need for repetitive inline styling.

Creating a Custom Divider Component

For more complex dividers or frequently used patterns, creating a custom component is often the best approach:

import React from 'react';
import { Divider, Box, Typography, styled } from '@mui/material';

// Create styled components for custom divider parts
const StyledDivider = styled(Divider)(({ theme, color = 'primary' }) => ({
'&::before, &::after': {
borderColor: theme.palette[color].light,
},
'& .MuiDivider-wrapper': {
backgroundColor: theme.palette.background.paper,
borderRadius: 16,
padding: theme.spacing(0, 2),
boxShadow: theme.shadows[1],
},
}));

const LabelWrapper = styled(Box)(({ theme, color = 'primary' }) => ({
display: 'flex',
alignItems: 'center',
gap: theme.spacing(1),
color: theme.palette[color].main,
}));

function CustomDividerWithIcon({
label,
icon: Icon,
color = 'primary',
...dividerProps
}) {
return (
<StyledDivider color={color} {...dividerProps}>
<LabelWrapper color={color}>
{Icon && <Icon fontSize="small" />}
<Typography
variant="button"
component="span"
sx={{ fontWeight: 'medium' }} >
{label}
</Typography>
</LabelWrapper>
</StyledDivider>
);
}

export default CustomDividerWithIcon;

This custom component provides a consistent way to create dividers with icons and labels, with customizable colors and styling.

Integrating Dividers with Other MUI Components

Dividers are particularly useful when integrated with other MUI components to create cohesive interfaces.

Dividers in Lists

Lists are one of the most common places to use dividers:

import React from 'react';
import {
  List,
  ListItem,
  ListItemText,
  ListItemIcon,
  Divider,
  Box
} from '@mui/material';
import InboxIcon from '@mui/icons-material/Inbox';
import DraftsIcon from '@mui/icons-material/Drafts';
import SendIcon from '@mui/icons-material/Send';

function DividedList() {
return (
<Box sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}>
<List component="nav" aria-label="mailbox folders">
<ListItem button>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Inbox" />
</ListItem>

        {/* Standard divider */}
        <Divider />

        <ListItem button>
          <ListItemIcon>
            <DraftsIcon />
          </ListItemIcon>
          <ListItemText primary="Drafts" />
        </ListItem>

        {/* Inset divider aligns with text */}
        <Divider variant="inset" component="li" />

        <ListItem button>
          <ListItemIcon>
            <SendIcon />
          </ListItemIcon>
          <ListItemText primary="Sent Items" />
        </ListItem>

        {/* Divider with text label */}
        <Divider component="li">ARCHIVES</Divider>

        <ListItem button>
          <ListItemText primary="Archived Mail" secondary="From previous months" />
        </ListItem>
      </List>
    </Box>

);
}

export default DividedList;

In lists, the inset variant is particularly useful as it aligns the divider with the text content, creating a more polished look.

Dividers in Cards and Panels

Dividers can effectively separate content within cards:

import React from 'react';
import {
  Card,
  CardHeader,
  CardContent,
  CardActions,
  Button,
  Typography,
  Divider,
  Box
} from '@mui/material';

function DividedCard() {
return (
<Box sx={{ maxWidth: 400 }}>
<Card>
<CardHeader title="Product Information" />

        <Divider />

        <CardContent>
          <Typography variant="body2" color="text.secondary">
            Main product description and details go here.
          </Typography>
        </CardContent>

        <Divider>PRICING</Divider>

        <CardContent>
          <Typography variant="h6" color="primary" sx={{ fontWeight: 'bold' }}>
            $99.99
          </Typography>
          <Typography variant="caption" color="text.secondary">
            *Price may vary by location
          </Typography>
        </CardContent>

        <Divider />

        <CardActions>
          <Button size="small">Learn More</Button>
          <Button size="small" color="primary">Add to Cart</Button>
        </CardActions>
      </Card>
    </Box>

);
}

export default DividedCard;

In cards, dividers help organize different types of information and actions, making the content more scannable and structured.

Dividers in Forms

Dividers can help organize form sections:

import React from 'react';
import {
  Box,
  TextField,
  Button,
  Divider,
  Grid,
  Typography,
  FormControlLabel,
  Checkbox
} from '@mui/material';

function DividedForm() {
return (
<Box
component="form"
sx={{
        width: '100%',
        maxWidth: 600,
        mx: 'auto',
        p: 3,
      }} >
<Typography variant="h5" gutterBottom>
Registration Form
</Typography>

      <Divider textAlign="left">PERSONAL INFORMATION</Divider>

      <Grid container spacing={2} sx={{ mt: 2, mb: 4 }}>
        <Grid item xs={12} sm={6}>
          <TextField
            required
            fullWidth
            label="First Name"
            autoFocus
          />
        </Grid>
        <Grid item xs={12} sm={6}>
          <TextField
            required
            fullWidth
            label="Last Name"
          />
        </Grid>
        <Grid item xs={12}>
          <TextField
            required
            fullWidth
            label="Email Address"
            type="email"
          />
        </Grid>
      </Grid>

      <Divider textAlign="left">ACCOUNT DETAILS</Divider>

      <Grid container spacing={2} sx={{ mt: 2, mb: 4 }}>
        <Grid item xs={12}>
          <TextField
            required
            fullWidth
            label="Username"
          />
        </Grid>
        <Grid item xs={12} sm={6}>
          <TextField
            required
            fullWidth
            label="Password"
            type="password"
          />
        </Grid>
        <Grid item xs={12} sm={6}>
          <TextField
            required
            fullWidth
            label="Confirm Password"
            type="password"
          />
        </Grid>
      </Grid>

      <Divider textAlign="left">PREFERENCES</Divider>

      <Box sx={{ mt: 2, mb: 4 }}>
        <FormControlLabel
          control={<Checkbox color="primary" />}
          label="Receive email notifications"
        />
        <FormControlLabel
          control={<Checkbox color="primary" />}
          label="Subscribe to newsletter"
        />
      </Box>

      <Divider />

      <Box sx={{ mt: 3, display: 'flex', justifyContent: 'flex-end', gap: 2 }}>
        <Button variant="outlined">Cancel</Button>
        <Button variant="contained" color="primary" type="submit">
          Register
        </Button>
      </Box>
    </Box>

);
}

export default DividedForm;

In forms, dividers with labels create clear sections that help users understand the form structure and complete it more efficiently.

Accessibility Considerations

When using dividers with labels, proper accessibility is crucial for users with screen readers or other assistive technologies.

Semantic HTML and ARIA Attributes

import React from 'react';
import { Divider, Box, Typography } from '@mui/material';

function AccessibleDivider({ label, headingLevel = 'h3', ...props }) {
// Determine the heading component based on the level
const HeadingComponent = headingLevel;

return (
<Box role="presentation" sx={{ width: '100%', my: 2 }}>
{/* Screen reader only heading */}
<Typography 
        variant="srOnly" 
        component={HeadingComponent}
      >
{label}
</Typography>

      {/* Visual divider with label */}
      <Divider
        aria-hidden="true"  // Hide from screen readers since we have the heading
        {...props}
      >
        {label}
      </Divider>
    </Box>

);
}

export default AccessibleDivider;

This approach ensures that:

  1. Screen readers announce the section properly via a semantic heading
  2. The visual divider is hidden from screen readers to avoid duplicate announcements
  3. The visual hierarchy is maintained for sighted users

Keyboard Navigation

For interactive dividers (like collapsible section headers), ensure keyboard navigation works properly:

import React, { useState } from 'react';
import { 
  Divider, 
  Box, 
  Typography, 
  Collapse, 
  IconButton
} from '@mui/material';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import ExpandLessIcon from '@mui/icons-material/ExpandLess';

function CollapsibleSection({ title, children }) {
const [expanded, setExpanded] = useState(false);

const toggleExpanded = () => {
setExpanded((prev) => !prev);
};

return (
<Box sx={{ width: '100%', my: 2 }}>
<Divider
textAlign="left"
sx={{
          cursor: 'pointer',
          '&:hover': {
            bgcolor: 'action.hover',
          },
        }} >
<Box
component="button"
onClick={toggleExpanded}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
toggleExpanded();
}
}}
sx={{
            display: 'flex',
            alignItems: 'center',
            gap: 1,
            border: 'none',
            background: 'none',
            padding: 0,
            cursor: 'pointer',
            color: 'inherit',
            font: 'inherit',
          }}
aria-expanded={expanded}
aria-controls={`section-${title.replace(/\s+/g, '-').toLowerCase()}`} >
<Typography variant="subtitle1" component="span">
{title}
</Typography>
<IconButton
size="small"
edge="end"
aria-label={expanded ? "collapse section" : "expand section"}
sx={{ p: 0 }}
tabIndex={-1} // Remove from tab order as the whole button is focusable >
{expanded ? <ExpandLessIcon /> : <ExpandMoreIcon />}
</IconButton>
</Box>
</Divider>

      <Collapse
        in={expanded}
        id={`section-${title.replace(/\s+/g, '-').toLowerCase()}`}
      >
        <Box sx={{ pt: 2, pb: 1 }}>
          {children}
        </Box>
      </Collapse>
    </Box>

);
}

export default CollapsibleSection;

This implementation ensures that:

  1. The section can be toggled with both mouse and keyboard
  2. Proper ARIA attributes inform screen readers about the expanded state
  3. The content is properly associated with its header via ID references

Best Practices and Common Issues

Best Practices

  1. Use semantic dividers: Choose the appropriate variant based on the context (fullWidth, inset, middle).

  2. Consistent spacing: Maintain consistent spacing around dividers throughout your application.

  3. Typography hierarchy: Use appropriate typography variants for divider labels that match your design system's hierarchy.

  4. Color contrast: Ensure sufficient contrast between divider lines, labels, and backgrounds.

  5. Responsive considerations: Adjust divider text alignment and styling for different screen sizes.

import React from 'react';
import { useTheme, useMediaQuery, Divider, Box } from '@mui/material';

function BestPracticeDivider({ label }) {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));

return (
<Box sx={{ my: { xs: 2, md: 3 } }}>
<Divider
textAlign={isMobile ? "center" : "left"}
sx={{
          '&::before, &::after': {
            borderColor: theme.palette.divider,
          },
          '& .MuiDivider-wrapper': {
            color: theme.palette.text.secondary,
            fontSize: isMobile ? '0.875rem' : '1rem',
            fontWeight: 'medium',
          },
        }} >
{label}
</Divider>
</Box>
);
}

export default BestPracticeDivider;

Common Issues and Solutions

Issue 1: Divider Not Spanning Full Width

If your divider isn't spanning the full width as expected, check container styling:

import React from 'react';
import { Divider, Box } from '@mui/material';

// Problem: Divider not spanning full width
function ProblemExample() {
return (
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
<Divider /> {/* May not span full width in some flex layouts */}
</Box>
);
}

// Solution: Use width: '100%'
function SolutionExample() {
return (
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
<Divider sx={{ width: '100%' }} />
</Box>
);
}

export { ProblemExample, SolutionExample };

Issue 2: Vertical Divider Height Problems

Vertical dividers often need special handling for height:

import React from 'react';
import { Divider, Box } from '@mui/material';

// Problem: Vertical divider not taking full height
function ProblemExample() {
return (
<Box sx={{ display: 'flex', height: 100 }}>
<Box>Left content</Box>
<Divider orientation="vertical" /> {/* May not take full height */}
<Box>Right content</Box>
</Box>
);
}

// Solution: Use flexItem prop
function SolutionExample() {
return (
<Box sx={{ display: 'flex', height: 100 }}>
<Box>Left content</Box>
<Divider orientation="vertical" flexItem />
<Box>Right content</Box>
</Box>
);
}

export { ProblemExample, SolutionExample };

Issue 3: Text Alignment in RTL Layouts

For right-to-left languages, you need to handle text alignment differently:

import React from 'react';
import { Divider, Box, ThemeProvider, createTheme } from '@mui/material';
import rtlPlugin from 'stylis-plugin-rtl';
import { prefixer } from 'stylis';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';

// Create RTL cache
const rtlCache = createCache({
key: 'muirtl',
stylisPlugins: [prefixer, rtlPlugin],
});

// Create RTL theme
const rtlTheme = createTheme({
direction: 'rtl',
});

function RTLDivider() {
return (
<CacheProvider value={rtlCache}>
<ThemeProvider theme={rtlTheme}>
<Box sx={{ width: '100%', dir: 'rtl' }}>
{/* In RTL, "left" actually appears on the right side */}
<Divider textAlign="left">القسم الأول</Divider>
<Box sx={{ my: 2 }} />

          {/* For RTL interfaces, "right" appears on the left side */}
          <Divider textAlign="right">القسم الثاني</Divider>
        </Box>
      </ThemeProvider>
    </CacheProvider>

);
}

export default RTLDivider;

Issue 4: Inconsistent Spacing Around Dividers

To maintain consistent spacing around dividers:

import React from 'react';
import { Box, Divider, styled } from '@mui/material';

// Create a consistent spacing wrapper
const DividerSpacing = styled(Box)(({ theme }) => ({
marginTop: theme.spacing(3),
marginBottom: theme.spacing(3),
}));

function ConsistentDividers() {
return (
<Box>
<DividerSpacing>
<Divider>SECTION ONE</Divider>
</DividerSpacing>

      {/* Content here */}

      <DividerSpacing>
        <Divider>SECTION TWO</Divider>
      </DividerSpacing>

      {/* More content */}

      <DividerSpacing>
        <Divider>SECTION THREE</Divider>
      </DividerSpacing>
    </Box>

);
}

export default ConsistentDividers;

Wrapping Up

The MUI Divider component offers a powerful way to organize your React applications with visually appealing section dividers. We've explored everything from basic implementation to advanced customization techniques, responsive designs, and accessibility considerations.

By leveraging the flexibility of the Divider component with labels, you can create clear visual hierarchies that guide users through your interface. Whether you're building forms, product pages, dashboards, or any complex UI, well-designed dividers with labels can significantly improve the user experience by providing context and structure.

Remember to keep accessibility in mind, maintain consistent styling through your theme, and consider the responsive behavior of your dividers across different device sizes. With these considerations in place, you'll be able to create professional, polished interfaces that are both visually appealing and functional.