Skip to main content

Styling React Components

Level: Beginner

ℹ️ What You'll Learn
  • Inline styles: when and how to use them for dynamic styling
  • CSS Classes: maintaining styles across components
  • CSS Modules: preventing class name collisions and scoping
  • Tailwind CSS: rapid development with utility classes
  • Dynamic styling based on props and state
  • Conditional styling for different states (active, selected, disabled)
  • Responsive design in React components
  • When to choose each approach for School Management System screens

Why This Matters

Styling React Components is part of building maintainable React applications. You will use it when creating student dashboards, forms, tables, API-connected screens, routing flows, and reusable UI components.

React components need to look good. There are multiple ways to style them.

The Problem

Beginners often write React code that works for a small demo but becomes difficult when data, forms, API calls, and reusable components grow. This lesson explains Styling React Components in a way that helps you build predictable UI for real .NET Web API projects.

Approach 1: Inline Styles

Pass a JavaScript object to style attribute.

function StudentCard({ student }) {
const cardStyle = {
border: "1px solid #ddd",
padding: "20px",
borderRadius: "8px",
backgroundColor: "#f9f9f9"
};

return (
<div style={cardStyle}>
<h3 style={{ color: "#333", fontSize: "18px" }}>{student.name}</h3>
<p style={{ color: "#666" }}>Class: {student.className}</p>
</div>
);
}

Pros: Scoped to component, dynamic styling Cons: Verbose, no hover/media queries, not reusable

Approach 2: CSS Classes

Define CSS in a file, apply with className.

// StudentCard.jsx
function StudentCard({ student }) {
return (
<div className="student-card">
<h3 className="student-name">{student.name}</h3>
<p className="student-class">Class: {student.className}</p>
</div>
);
}
/* StudentCard.css */
.student-card {
border: 1px solid #ddd;
padding: 20px;
border-radius: 8px;
background-color: #f9f9f9;
}

.student-name {
color: #333;
font-size: 18px;
margin: 0;
}

.student-class {
color: #666;
}

/* Hover effect */
.student-card:hover {
background-color: #f0f0f0;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

/* Responsive */
@media (max-width: 600px) {
.student-card {
padding: 10px;
}
}

Import the CSS:

import './StudentCard.css';

function StudentCard({ student }) {
return (
<div className="student-card">
<h3 className="student-name">{student.name}</h3>
<p className="student-class">Class: {student.className}</p>
</div>
);
}

Pros: Familiar, supports full CSS (hover, media queries) Cons: Class name collisions across files, bloated CSS

Approach 3: CSS Modules (Scoped CSS)

CSS files that scope classes to components automatically.

/* StudentCard.module.css */
.card {
border: 1px solid #ddd;
padding: 20px;
border-radius: 8px;
}

.name {
color: #333;
font-size: 18px;
}

.card:hover {
background-color: #f0f0f0;
}
// StudentCard.jsx
import styles from './StudentCard.module.css';

function StudentCard({ student }) {
return (
<div className={styles.card}>
<h3 className={styles.name}>{student.name}</h3>
<p>Class: {student.className}</p>
</div>
);
}

Classes are scoped — .card in StudentCard.module.css won't conflict with .card elsewhere.

Pros: Scoped, full CSS support, no collisions Cons: Slightly different syntax

Approach 4: Tailwind CSS (Utility Classes)

Use pre-made utility classes.

Install:

npm install -D tailwindcss
npx tailwindcss init

Use:

function StudentCard({ student }) {
return (
<div className="border border-gray-300 p-5 rounded-lg bg-gray-50 hover:bg-gray-100">
<h3 className="text-gray-800 text-lg font-semibold">{student.name}</h3>
<p className="text-gray-600">Class: {student.className}</p>
</div>
);
}

Pros: Fast, small bundle, consistent design Cons: Learning curve, verbose classes, requires setup

Dynamic Styling

Often you need to style based on props or state.

With Inline Styles

function StudentBadge({ status }) {
const statusColors = {
'Active': { backgroundColor: '#4CAF50', color: 'white' },
'Inactive': { backgroundColor: '#f44336', color: 'white' },
'Graduated': { backgroundColor: '#2196F3', color: 'white' }
};

return (
<span style={statusColors[status] || statusColors['Inactive']}>
{status}
</span>
);
}

With CSS Classes

function StudentBadge({ status }) {
const statusClass = status.toLowerCase(); // 'active', 'inactive', etc.

return <span className={`badge badge-${statusClass}`}>{status}</span>;
}
.badge {
padding: 4px 8px;
border-radius: 4px;
font-weight: bold;
}

.badge-active {
background-color: #4CAF50;
color: white;
}

.badge-inactive {
background-color: #f44336;
color: white;
}

.badge-graduated {
background-color: #2196F3;
color: white;
}

With Tailwind

function StudentBadge({ status }) {
const statusClasses = {
'Active': 'bg-green-500 text-white',
'Inactive': 'bg-red-500 text-white',
'Graduated': 'bg-blue-500 text-white'
};

return (
<span className={`px-2 py-1 rounded font-semibold ${statusClasses[status]}`}>
{status}
</span>
);
}

Conditional Styling

Apply styles based on conditions.

function StudentRow({ student, isSelected }) {
return (
<tr className={isSelected ? 'selected' : 'normal'}>
<td>{student.name}</td>
<td>{student.marks}</td>
</tr>
);
}
.normal {
background-color: white;
}

.selected {
background-color: #e3f2fd;
border-left: 3px solid #2196F3;
}

Or with Tailwind:

function StudentRow({ student, isSelected }) {
return (
<tr className={isSelected ? 'bg-blue-50 border-l-4 border-blue-500' : 'bg-white'}>
<td>{student.name}</td>
<td>{student.marks}</td>
</tr>
);
}

Real Example: Teacher Card

import styles from './TeacherCard.module.css';

function TeacherCard({ teacher, onClick, isSelected }) {
const containerClass = isSelected
? `${styles.card} ${styles.selected}`
: styles.card;

return (
<div className={containerClass} onClick={onClick}>
<div className={styles.header}>
<h3 className={styles.name}>{teacher.name}</h3>
<span className={styles.experience}>{teacher.experienceYears}y</span>
</div>
<p className={styles.subject}>{teacher.subject}</p>
<p className={styles.qualification}>{teacher.qualification}</p>
</div>
);
}

export default TeacherCard;
/* TeacherCard.module.css */
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 16px;
margin: 8px 0;
cursor: pointer;
transition: all 0.2s ease;
}

.card:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
border-color: #2196F3;
}

.card.selected {
background-color: #e3f2fd;
border-color: #2196F3;
border-left: 4px solid #2196F3;
}

.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}

.name {
margin: 0;
color: #333;
font-size: 16px;
font-weight: 600;
}

.experience {
background-color: #f0f0f0;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
color: #666;
}

.subject {
margin: 4px 0;
color: #666;
font-weight: 500;
}

.qualification {
margin: 4px 0;
color: #999;
font-size: 14px;
}

When to Use Each Approach in SMS

ScenarioApproachExample
Student card stylingCSS Modules.card { border: 1px solid #ddd; }
Active/inactive status badgeInline styles or Tailwind{status === 'Active' ? 'bg-green-500' : 'bg-red-500'}
Form input with error stateCSS Modules + conditional.input.error { border-color: red; }
Dashboard theme (light/dark)CSS Modules or TailwindDynamic className based on theme prop
Attendance table row highlightsCSS Modules + isSelected.row.selected { background-color: #e3f2fd; }
Fee payment status colorsInline object mapstatusColors[status] object lookup
Responsive student list gridTailwind or CSS media queriesgrid grid-cols-1 md:grid-cols-2 lg:grid-cols-3

Which Approach to Use?

  • Inline styles: Small components, dynamic styling based on props, status badges
  • CSS Classes: Standard approach, full CSS features, easy to learn, recommended for teams
  • CSS Modules: Medium+ projects, avoid class name collisions, maintainable at scale
  • Tailwind: Fast prototyping, design consistency, team adoption, no CSS file management

For School Management System:

  • Use CSS Modules (scoped, maintainable, prevents naming collisions)
  • Or Tailwind (faster development, consistent design tokens)
  • Avoid raw inline styles for complex styling (harder to maintain)

Responsive Design

/* CSS Classes */
.student-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 16px;
}

@media (max-width: 768px) {
.student-list {
grid-template-columns: 1fr;
}
}
// Tailwind
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{students.map(student => (
<StudentCard key={student.id} student={student} />
))}
</div>

Key Takeaways

  • Multiple styling approaches exist
  • CSS Modules prevent class name collisions
  • Tailwind is fast but requires learning classes
  • Responsive design is essential
  • Next: useEffect for side effects
⚠️ Common Mistakes
  1. Using class instead of className — React needs className
  2. Forgetting to scope CSS — Use modules or BEM naming
  3. Over-styling inline — Extract to CSS file for complex styles
  4. Not testing responsive — Always test on mobile
💡 CSS Architecture

Keep CSS organized:

  • One .module.css per component
  • Share utility CSS in global.css
  • Use consistent naming (BEM or component-based)
🤖Use AI to Learn Faster

Use ChatGPT, Claude, or Copilot to go deeper on React Styling. Try these prompts:

  • "When would you use inline styles vs. CSS modules?"
  • "What problem does CSS Modules solve?"
  • "What are the pros and cons of Tailwind CSS?"
  • "Quiz me on React styling approaches"

💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.

Quick Definitions

  • Styling React Components - The main React concept explained in this lesson.
  • Component - A reusable function that returns UI.
  • Props/state/effects - Core React ideas used to pass data, remember data, and run side effects.
  • Real project usage - How this appears in forms, dashboards, routes, and API-connected pages.

Common Mistakes

  • Copying React code without understanding data flow
  • Mutating arrays or objects directly instead of creating new values
  • Forgetting keys, dependencies, loading states, or error states where needed
  • Putting too much logic in one component
  • Not testing the screen with realistic School Management System data

Practice Task

Create a small React example using Styling React Components. Keep it focused on one School Management System screen.

Suggested practice:

  1. Build a small component or page for students, attendance, marks, or fees.
  2. Pass realistic data into the component.
  3. Add one success state and one empty/error state where relevant.
  4. Explain the data flow in your own words.
  5. Rebuild the same example once without looking at the article.

Quick Revision

QuestionAnswer
What is the main idea?Understand and apply Styling React Components in React.
Where is it used?Student dashboards, forms, tables, routes, and API-connected screens.
What should beginners focus on?Clear components, predictable data flow, and small examples.
What is the best debugging habit?Check props, state, render output, and browser console step by step.
🎯 How would you explain Styling React Components in an interview?

Styling React Components is a React concept used to build clear, reusable, and predictable user interfaces. I would explain the problem it solves, show a small component example, and mention a common mistake beginners should avoid.

🎯 Where is this used in a real React project?

It is used in screens like student lists, admission forms, attendance dashboards, marks reports, routing pages, and API-connected admin panels.

Next Article

useEffect Hook — Side Effects ->

nexcoding.in