Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Styling in React

Styling Approaches

ApproachProsCons
Inline stylesSimple, dynamicNo pseudo-classes, verbose
CSS filesFamiliar, full CSSGlobal scope, naming conflicts
CSS ModulesScoped, no conflictsSlightly verbose
Styled ComponentsComponent-scoped, dynamicRuntime overhead, learning curve
Tailwind CSSFast, consistent, no CSS filesLong class strings, learning curve
CSS Modules, Styled Components, Tailwind, clsx
// Button.module.css
// .btn { padding: 8px 16px; border-radius: 4px; cursor: pointer; }
// .primary { background: #3498db; color: white; }
// .danger  { background: #e74c3c; color: white; }
// .sm { padding: 4px 8px; font-size: 0.875rem; }
// .lg { padding: 12px 24px; font-size: 1.125rem; }

// Button.jsx — CSS Modules
import styles from './Button.module.css'

function Button({ label, variant = 'primary', size = 'md' }) {
    // CSS Modules auto-generates unique class names — no conflicts!
    const className = [
        styles.btn,
        styles[variant],  // styles.primary or styles.danger
        styles[size],     // styles.sm, styles.md, styles.lg
    ].filter(Boolean).join(' ')

    return <button className={className}>{label}</button>
}

// With clsx library for conditional classes
import clsx from 'clsx'  // npm install clsx

function Button2({ label, variant, size, disabled, loading }) {
    return (
        <button
            className={clsx(
                styles.btn,
                styles[variant],
                styles[size],
                { [styles.disabled]: disabled, [styles.loading]: loading }
            )}
            disabled={disabled || loading}
        >
            {label}
        </button>
    )
}
// npm install styled-components
import styled, { css, ThemeProvider } from 'styled-components'

// Basic styled component
const Button = styled.button`
    padding: 8px 16px;
    border-radius: 4px;
    cursor: pointer;
    border: none;
    font-size: 1rem;
    transition: all 0.2s;

    /* Dynamic styles based on props */
    background: ${props => props.variant === 'danger' ? '#e74c3c' : '#3498db'};
    color: white;

    &:hover {
        opacity: 0.9;
        transform: translateY(-1px);
    }

    &:disabled {
        opacity: 0.5;
        cursor: not-allowed;
    }

    /* Conditional CSS with css helper */
    ${props => props.size === 'lg' && css`
        padding: 12px 24px;
        font-size: 1.125rem;
    `}
`

// Extend existing component
const DangerButton = styled(Button)`
    background: #e74c3c;
    &:hover { background: #c0392b; }
`

// Theme support
const theme = {
    colors: { primary: '#3498db', danger: '#e74c3c' },
    spacing: { sm: '4px', md: '8px', lg: '16px' }
}

function App() {
    return (
        <ThemeProvider theme={theme}>
            <Button variant="primary">Save</Button>
            <DangerButton>Delete</DangerButton>
            <Button size="lg">Large Button</Button>
        </ThemeProvider>
    )
}
// Tailwind CSS — utility-first CSS framework
// npm install -D tailwindcss postcss autoprefixer
// npx tailwindcss init -p

// tailwind.config.js
// content: ['./src/**/*.{js,jsx,ts,tsx}']

// Button with Tailwind
function Button({ label, variant = 'primary', size = 'md', disabled }) {
    const baseClasses = 'rounded font-medium transition-all duration-200 cursor-pointer'

    const variantClasses = {
        primary:   'bg-blue-500 text-white hover:bg-blue-600',
        secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300',
        danger:    'bg-red-500 text-white hover:bg-red-600',
    }

    const sizeClasses = {
        sm: 'px-3 py-1.5 text-sm',
        md: 'px-4 py-2 text-base',
        lg: 'px-6 py-3 text-lg',
    }

    return (
        <button
            className={`${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]} ${disabled ? 'opacity-50 cursor-not-allowed' : ''}`}
            disabled={disabled}
        >
            {label}
        </button>
    )
}

// With clsx + tailwind-merge (handles conflicting classes)
import clsx from 'clsx'
import { twMerge } from 'tailwind-merge'  // npm install tailwind-merge

function cn(...inputs) {
    return twMerge(clsx(inputs))
}

function Card({ className, children }) {
    return (
        <div className={cn(
            'rounded-lg border bg-white p-6 shadow-sm',
            className  // allows overriding from parent
        )}>
            {children}
        </div>
    )
}

// Usage
<Card className="bg-blue-50 border-blue-200">
    Custom card
</Card>

Previous Next

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.