Skillversitas

Responsive Design

Responsive design is a web design approach that ensures a page displays optimally at every screen size — from small smartphones to ultrawide monitors. Responsive design is not just about media queries; it also includes the viewport meta tag, fluid units, responsive images, responsive typography, and flexible layout patterns.

The main goals of responsive design:

  • Content is easy to read on every device
  • Intuitive navigation without zooming or horizontal scrolling
  • Images and visual elements adapt without breaking
  • Performance stays optimal on mobile

The key components:

  • Viewport meta tag — controls the display area on mobile
  • Fluid layouts — layouts using percentages
  • Responsive units — %, em, rem, vw, vh
  • Responsive images — images that adapt to their container
  • Responsive typography — text that scales with the viewport

Code Example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Responsive Design</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    /* ===== Viewport & Base ===== */
    html {
      font-size: 16px;
      scroll-behavior: smooth;
    }

    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      color: #333;
      line-height: 1.6;
    }

    /* ===== Responsive Typography ===== */
    .hero {
      background: linear-gradient(135deg, #1a1a2e, #16213e);
      color: white;
      padding: 80px 20px;
      text-align: center;
    }

    .hero h1 {
      font-size: clamp(2rem, 5vw, 4rem);
      font-weight: 800;
      margin-bottom: 15px;
      line-height: 1.2;
    }

    .hero p {
      font-size: clamp(1rem, 2.5vw, 1.4rem);
      opacity: 0.8;
      max-width: 700px;
      margin: 0 auto 30px;
    }

    .hero-btn {
      display: inline-block;
      padding: 14px 36px;
      background: #667eea;
      color: white;
      text-decoration: none;
      border-radius: 8px;
      font-size: clamp(0.9rem, 2vw, 1.1rem);
      font-weight: 600;
      transition: background 0.3s, transform 0.3s;
    }

    .hero-btn:hover {
      background: #764ba2;
      transform: translateY(-2px);
    }

    /* ===== Fluid Container ===== */
    .container {
      width: min(90%, 1200px);
      margin: 0 auto;
      padding: 0 20px;
    }

    /* ===== Responsive Grid ===== */
    .section {
      padding: 60px 0;
    }

    .section-title {
      font-size: clamp(1.5rem, 4vw, 2.5rem);
      text-align: center;
      margin-bottom: 10px;
      color: #1a1a2e;
    }

    .section-subtitle {
      text-align: center;
      color: #888;
      margin-bottom: 40px;
      font-size: clamp(0.85rem, 2vw, 1rem);
    }

    /* 12-column responsive grid */
    .grid {
      display: grid;
      grid-template-columns: repeat(12, 1fr);
      gap: 20px;
    }

    .col-12 { grid-column: span 12; }
    .col-6  { grid-column: span 6; }
    .col-4  { grid-column: span 4; }
    .col-3  { grid-column: span 3; }

    .card {
      background: white;
      border-radius: 12px;
      padding: 30px 20px;
      text-align: center;
      box-shadow: 0 2px 10px rgba(0,0,0,0.06);
      transition: transform 0.3s, box-shadow 0.3s;
    }

    .card:hover {
      transform: translateY(-5px);
      box-shadow: 0 8px 25px rgba(0,0,0,0.12);
    }

    .card-icon {
      font-size: 2.5rem;
      margin-bottom: 15px;
    }

    .card h3 {
      color: #1a1a2e;
      margin-bottom: 8px;
    }

    .card p {
      color: #666;
      font-size: 0.9rem;
      line-height: 1.6;
    }

    /* ===== Responsive Image ===== */
    .image-section {
      padding: 60px 0;
      background: #f8f9fa;
    }

    .image-grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 20px;
    }

    .image-item {
      border-radius: 12px;
      overflow: hidden;
      box-shadow: 0 2px 10px rgba(0,0,0,0.08);
    }

    .image-item img {
      width: 100%;
      height: 200px;
      object-fit: cover;
      display: block;
      transition: transform 0.4s;
    }

    .image-item:hover img {
      transform: scale(1.05);
    }

    .image-caption {
      padding: 15px;
      font-size: 0.9rem;
      color: #555;
      text-align: center;
      background: white;
    }

    /* ===== Units Comparison ===== */
    .units-section {
      padding: 60px 0;
    }

    .units-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
      gap: 25px;
    }

    .unit-card {
      background: white;
      border-radius: 12px;
      padding: 25px;
      box-shadow: 0 2px 10px rgba(0,0,0,0.06);
    }

    .unit-card h4 {
      color: #667eea;
      margin-bottom: 10px;
      font-family: monospace;
      font-size: 1.1rem;
    }

    .unit-card p {
      color: #555;
      font-size: 0.85rem;
      line-height: 1.6;
      margin-bottom: 15px;
    }

    .unit-demo {
      background: #f0f2f5;
      border-radius: 8px;
      padding: 15px;
      text-align: center;
    }

    .unit-box {
      background: linear-gradient(135deg, #667eea, #764ba2);
      color: white;
      padding: 10px;
      border-radius: 6px;
      font-size: 0.8rem;
      font-weight: 600;
      margin-bottom: 5px;
    }

    .unit-rem { width: 10rem; }
    .unit-em { width: 10em; }
    .unit-vw { width: 20vw; }
    .unit-pct { width: 80%; }

    /* ===== Responsive Navbar ===== */
    .resp-nav {
      background: #1a1a2e;
      padding: 15px 0;
      position: sticky;
      top: 0;
      z-index: 100;
    }

    .resp-nav-inner {
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .resp-nav-brand {
      color: white;
      font-size: 1.4rem;
      font-weight: bold;
    }

    .resp-nav-brand span { color: #667eea; }

    .resp-nav-links {
      display: flex;
      list-style: none;
      gap: 25px;
    }

    .resp-nav-links a {
      color: #aaa;
      text-decoration: none;
      font-size: 0.9rem;
      transition: color 0.3s;
    }

    .resp-nav-links a:hover { color: #667eea; }

    .resp-hamburger {
      display: none;
      background: none;
      border: none;
      cursor: pointer;
      padding: 5px;
    }

    .resp-hamburger span {
      display: block;
      width: 25px;
      height: 3px;
      background: white;
      margin: 5px 0;
      border-radius: 2px;
    }

    /* ===== Responsive Table ===== */
    .table-section {
      padding: 60px 0;
      background: #f8f9fa;
    }

    .table-wrapper {
      overflow-x: auto;
      -webkit-overflow-scrolling: touch;
    }

    .resp-table {
      width: 100%;
      border-collapse: collapse;
      background: white;
      border-radius: 12px;
      overflow: hidden;
      box-shadow: 0 2px 10px rgba(0,0,0,0.06);
      min-width: 600px;
    }

    .resp-table th,
    .resp-table td {
      padding: 14px 20px;
      text-align: left;
      border-bottom: 1px solid #eee;
    }

    .resp-table th {
      background: #1a1a2e;
      color: white;
      font-weight: 600;
    }

    .resp-table tr:last-child td { border-bottom: none; }

    /* ===== Footer ===== */
    .footer {
      background: #1a1a2e;
      color: #aaa;
      padding: 50px 20px 30px;
    }

    .footer-grid {
      display: grid;
      grid-template-columns: 2fr 1fr 1fr 1fr;
      gap: 30px;
      max-width: 1200px;
      margin: 0 auto;
    }

    .footer h4 {
      color: white;
      margin-bottom: 15px;
    }

    .footer p, .footer a {
      color: #888;
      text-decoration: none;
      font-size: 0.85rem;
      line-height: 1.8;
    }

    .footer a:hover { color: #667eea; }

    .footer-bottom {
      text-align: center;
      margin-top: 30px;
      padding-top: 20px;
      border-top: 1px solid rgba(255,255,255,0.1);
      font-size: 0.8rem;
      color: #555;
    }

    /* ===== Responsive Breakpoints ===== */

    /* Tablet landscape & small desktop */
    @media (max-width: 1024px) {
      .col-4 { grid-column: span 6; }
      .col-3 { grid-column: span 6; }

      .footer-grid {
        grid-template-columns: 1fr 1fr;
      }
    }

    /* Tablet portrait */
    @media (max-width: 768px) {
      .col-6 { grid-column: span 12; }
      .col-4 { grid-column: span 12; }
      .col-3 { grid-column: span 6; }

      .image-grid {
        grid-template-columns: repeat(2, 1fr);
      }

      .resp-nav-links {
        display: none;
      }

      .resp-hamburger {
        display: block;
      }

      .hero {
        padding: 60px 20px;
      }

      .footer-grid {
        grid-template-columns: 1fr;
      }
    }

    /* Mobile */
    @media (max-width: 480px) {
      .col-3 { grid-column: span 12; }

      .image-grid {
        grid-template-columns: 1fr;
      }

      .hero {
        padding: 40px 15px;
      }

      .section {
        padding: 40px 0;
      }
    }
  </style>
</head>
<body>

  <nav class="resp-nav">
    <div class="container resp-nav-inner">
      <div class="resp-nav-brand">Skill<span>versitas</span></div>
      <ul class="resp-nav-links">
        <li><a href="#">Home</a></li>
        <li><a href="#">Tutorial</a></li>
        <li><a href="#">Kursus</a></li>
        <li><a href="#">Blog</a></li>
        <li><a href="#">Kontak</a></li>
      </ul>
      <button class="resp-hamburger">
        <span></span>
        <span></span>
        <span></span>
      </button>
    </div>
  </nav>

  <section class="hero">
    <div class="container">
      <h1>Responsive Design</h1>
      <p>Web design that adapts perfectly to every device — from mobile to desktop</p>
      <a href="#content" class="hero-btn">Learn Now</a>
    </div>
  </section>

  <div id="content">

    <section class="section">
      <div class="container">
        <h2 class="section-title">Responsive Grid System</h2>
        <p class="section-subtitle">Resize the browser to watch the grid adapt</p>
        <div class="grid">
          <div class="col-3">
            <div class="card">
              <div class="card-icon">📱</div>
              <h3>Mobile</h3>
              <p>≤ 480px — single column layout</p>
            </div>
          </div>
          <div class="col-3">
            <div class="card">
              <div class="card-icon">📋</div>
              <h3>Tablet</h3>
              <p>≤ 768px — two column layout</p>
            </div>
          </div>
          <div class="col-3">
            <div class="card">
              <div class="card-icon">💻</div>
              <h3>Laptop</h3>
              <p>≤ 1024px — three column layout</p>
            </div>
          </div>
          <div class="col-3">
            <div class="card">
              <div class="card-icon">🖥️</div>
              <h3>Desktop</h3>
              <p>> 1024px — four column layout</p>
            </div>
          </div>
        </div>
      </div>
    </section>

    <section class="image-section">
      <div class="container">
        <h2 class="section-title">Responsive Images</h2>
        <p class="section-subtitle">Images that stay proportional on all screens</p>
        <div class="image-grid">
          <div class="image-item">
            <img src="https://picsum.photos/seed/css1/600/400" alt="CSS Tutorial">
            <div class="image-caption">Tutorial CSS Dasar</div>
          </div>
          <div class="image-item">
            <img src="https://picsum.photos/seed/css2/600/400" alt="Flexbox">
            <div class="image-caption">Flexbox Layout</div>
          </div>
          <div class="image-item">
            <img src="https://picsum.photos/seed/css3/600/400" alt="Grid">
            <div class="image-caption">CSS Grid System</div>
          </div>
        </div>
      </div>
    </section>

    <section class="units-section">
      <div class="container">
        <h2 class="section-title">Responsive Units</h2>
        <p class="section-subtitle">Units that enable flexible design</p>
        <div class="units-grid">
          <div class="unit-card">
            <h4>% (Persentase)</h4>
            <p>Relative to the parent element. Ideal for layout widths.</p>
            <div class="unit-demo">
              <div class="unit-box unit-pct">width: 80%</div>
            </div>
          </div>
          <div class="unit-card">
            <h4>rem (Root Em)</h4>
            <p>Relative to the root font size (&lt;html&gt;). Great for spacing and typography.</p>
            <div class="unit-demo">
              <div class="unit-box unit-rem">width: 10rem</div>
            </div>
          </div>
          <div class="unit-card">
            <h4>em (Element Em)</h4>
            <p>Relative to the parent font size. Useful for inline padding/margins.</p>
            <div class="unit-demo">
              <div class="unit-box unit-em">width: 10em</div>
            </div>
          </div>
          <div class="unit-card">
            <h4>vw (Viewport Width)</h4>
            <p>A percentage of the viewport width. 1vw = 1% of the screen width.</p>
            <div class="unit-demo">
              <div class="unit-box unit-vw">width: 20vw</div>
            </div>
          </div>
        </div>
      </div>
    </section>

    <section class="table-section">
      <div class="container">
        <h2 class="section-title">Responsive Table</h2>
        <p class="section-subtitle">Tables with horizontal scrolling on mobile</p>
        <div class="table-wrapper">
          <table class="resp-table">
            <thead>
              <tr>
                <th>Unit</th>
                <th>Relative To</th>
                <th>Best For</th>
                <th>Example</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>%</td>
                <td>Parent element</td>
                <td>Layout width</td>
                <td>width: 50%</td>
              </tr>
              <tr>
                <td>em</td>
                <td>Parent font-size</td>
                <td>Padding, margin inline</td>
                <td>padding: 1.5em</td>
              </tr>
              <tr>
                <td>rem</td>
                <td>Root font-size</td>
                <td>Typography, spacing</td>
                <td>font-size: 1.2rem</td>
              </tr>
              <tr>
                <td>vw</td>
                <td>Viewport width</td>
                <td>Fluid typography</td>
                <td>font-size: 3vw</td>
              </tr>
              <tr>
                <td>vh</td>
                <td>Viewport height</td>
                <td>Full-height sections</td>
                <td>min-height: 100vh</td>
              </tr>
              <tr>
                <td>px</td>
                <td>Absolute</td>
                <td>Borders, small details</td>
                <td>border: 1px solid</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </section>

  </div>

  <footer class="footer">
    <div class="footer-grid">
      <div>
        <h4>Skillversitas</h4>
        <p>The most complete programming learning platform.</p>
      </div>
      <div>
        <h4>Tutorial</h4>
        <a href="#">CSS Dasar</a><br>
        <a href="#">Flexbox</a><br>
        <a href="#">Grid</a><br>
        <a href="#">Responsive</a>
      </div>
      <div>
        <h4>Kursus</h4>
        <a href="#">HTML</a><br>
        <a href="#">JavaScript</a><br>
        <a href="#">React</a><br>
        <a href="#">Node.js</a>
      </div>
      <div>
        <h4>Kontak</h4>
        <a href="#">Email</a><br>
        <a href="#">Twitter</a><br>
        <a href="#">GitHub</a><br>
        <a href="#">Discord</a>
      </div>
    </div>
    <div class="footer-bottom">
      &copy; 2025 Skillversitas. All rights reserved.
    </div>
  </footer>

</body>
</html>

Code Explanation

Viewport Meta Tag

This tag is REQUIRED on every responsive page. Without it, mobile browsers will render the page as if it were 980px wide and then scale it down — making everything look tiny.

<meta name="viewport" content="width=device-width, initial-scale=1.0">
  • width=device-width — viewport width = device width
  • initial-scale=1.0 — initial zoom 100%

Fluid Layout with Percentages

A fluid layout uses percentages instead of fixed pixels, so it adapts to the parent's size:

.container {
  width: 90%;
  max-width: 1200px;
}

.sidebar { width: 25%; }
.main { width: 75%; }

Responsive Units

  • % — relative to the parent. Perfect for layout widths.
  • em — relative to the parent element's font size. Useful for inline spacing.
  • rem — relative to the root font size (<html>). Most consistent for spacing and typography.
  • vw — 1vw = 1% of the viewport width. For fluid typography.
  • vh — 1vh = 1% of the viewport height. For full-height sections.
  • px — absolute. Use for borders, shadows, and small details.
html { font-size: 16px; }

/* rem: based on the 16px root */
.title { font-size: 2rem; }     /* 32px */
.space { margin-bottom: 1.5rem; } /* 24px */

/* vw: based on viewport width */
.hero-title { font-size: 5vw; } /* 5% of the screen width */

clamp() for Fluid Typography

clamp(min, preferred, max) lets fonts scale fluidly between min and max without media queries:

h1 {
  font-size: clamp(1.5rem, 4vw, 3rem);
  /* minimum 1.5rem, ideal 4vw, maximum 3rem */
}

Responsive Images

Well-behaved images should:

img {
  max-width: 100%;    /* does not exceed the container */
  height: auto;       /* keep the aspect ratio */
  display: block;     /* remove the bottom gap */
}

/* object-fit to keep images proportional */
.gallery-img {
  width: 100%;
  height: 200px;
  object-fit: cover; /* crop without distortion */
}

HTML also supports the srcset and sizes attributes to serve different images based on resolution:

<img
  src="image-800.jpg"
  srcset="image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w"
  sizes="(max-width: 480px) 100vw, (max-width: 768px) 50vw, 33vw"
  alt="Responsive image"
>

Container Queries (Brief)

Container queries let styles change based on the size of the parent element, not the viewport:

.card-container {
  container-type: inline-size;
}

@container (min-width: 400px) {
  .card {
    display: flex;
    flex-direction: row;
  }
}

This enables truly modular components — styles adapt depending on where the component is placed.

Everyday Use Cases

1. Complete Landing Page

A responsive landing page using the viewport tag, fluid typography with clamp(), a responsive grid, and media queries for different breakpoints:

html { font-size: 16px; }

.hero-title {
  font-size: clamp(2rem, 5vw, 4rem);
}

.features-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 30px;
}

@media (max-width: 768px) {
  .hero { padding: 60px 20px; }
}

2. Responsive Grid without Media Queries

Using auto-fit and minmax() for a grid that adapts automatically:

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}

This grid automatically shows 4 columns on desktop, 2 on tablet, and 1 on mobile — without media queries.

3. Responsive Typography System

A typography system that scales with the viewport:

:root {
  --text-sm: clamp(0.8rem, 1.5vw, 0.9rem);
  --text-base: clamp(0.95rem, 2vw, 1.1rem);
  --text-lg: clamp(1.2rem, 3vw, 1.6rem);
  --text-xl: clamp(1.8rem, 4vw, 3rem);
}

body { font-size: var(--text-base); }
h1 { font-size: var(--text-xl); }
h2 { font-size: var(--text-lg); }
small { font-size: var(--text-sm); }

4. Stacking Responsive Cards

Cards that sit in a single row on desktop and stack on mobile:

.card-row {
  display: flex;
  gap: 20px;
}

.card-row .card {
  flex: 1;
  min-width: 0;
}

@media (max-width: 768px) {
  .card-row {
    flex-direction: column;
  }
}

5. Touch-Friendly Layout on Mobile

Increasing spacing and touch target size on mobile:

.button {
  padding: 10px 20px;
  min-height: 36px;
}

@media (max-width: 768px) {
  .button {
    padding: 16px 28px;
    min-height: 48px; /* minimum touch target */
  }

  .nav-link {
    padding: 15px;
    display: block;
  }
}

Conclusion

Responsive design is a comprehensive approach that includes the viewport meta tag (width=device-width, initial-scale=1.0), fluid layouts with percentages, responsive units (%, em, rem, vw, vh), responsive images (max-width: 100%, object-fit), and fluid typography with clamp(). Media queries are used for specific breakpoints: 480px (mobile), 768px (tablet), 1024px (laptop), 1200px (desktop). Use auto-fit + minmax() for grids that adapt automatically without media queries. Container queries allow styling based on the parent element for more modular components.