Skillversitas

CSS Outline & Overflow

What is Outline?

Outline is a line around an element, similar to a border, but with some important differences:

  • Outline does not affect the element's size (it takes up no space)
  • Outline is always rectangular (it does not follow border-radius)
  • Outline is always placed outside the border of the element
  • Outline cannot be set per side (there is no outline-top)

Outline is most often used for focus states on interactive elements such as inputs, buttons, and links.

Outline Properties

Property Description Example
outline-style Outline line style solid, dashed, dotted, double, groove, ridge, inset, outset, none
outline-width Thickness 1px, 2px, thin, medium, thick
outline-color Color #333, blue, rgb(52, 152, 219)
outline-offset Distance from the border 3px, -2px

Shorthand

outline: [width] [style] [color];
/* Example: outline: 3px solid #3498db; */

outline: 3px solid #3498db;
outline-offset: 2px;

Outline vs Border

Aspect Outline Border
Takes up space No Yes
Follows border-radius No Yes
Can be set per side No Yes
Offset from border Yes No
Used for Focus states Visual design

What is Overflow?

The overflow property determines what happens when an element's content exceeds the element's size.

Overflow Values

Value Description
visible Default — content is displayed even outside the element
hidden Overflowing content is clipped (no scroll)
scroll Always shows a scrollbar even if content does not overflow
auto A scrollbar only appears if content overflows

Overflow per Axis

overflow-x: auto; /* Horizontal overflow */
overflow-y: auto; /* Vertical overflow */

Code Example

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

    body {
      font-family: Arial, sans-serif;
      background-color: #f5f5f5;
      padding: 20px;
      color: #333;
    }

    h1 {
      margin-bottom: 25px;
    }

    .section {
      background-color: white;
      border-radius: 8px;
      padding: 20px;
      margin-bottom: 25px;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
    }

    h2 {
      margin-bottom: 15px;
      color: #2c3e50;
    }

    p {
      line-height: 1.6;
      color: #555;
      margin-bottom: 10px;
    }

    code {
      background-color: #f0f0f0;
      padding: 2px 6px;
      border-radius: 3px;
      font-size: 13px;
    }

    /* === Outline Styles === */
    .outline-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
      gap: 15px;
    }

    .outline-box {
      padding: 15px;
      text-align: center;
      font-size: 13px;
      font-weight: bold;
      background-color: #f8f9fa;
      border: 2px solid #ddd;
      border-radius: 4px;
    }

    .outline-solid { outline: 3px solid #e74c3c; }
    .outline-dashed { outline: 3px dashed #3498db; }
    .outline-dotted { outline: 3px dotted #2ecc71; }
    .outline-double { outline: 4px double #f39c12; }
    .outline-groove { outline: 4px groove #9b59b6; }
    .outline-ridge { outline: 4px ridge #1abc9c; }

    /* === Outline Offset === */
    .offset-grid {
      display: flex;
      gap: 20px;
      flex-wrap: wrap;
    }

    .offset-box {
      padding: 15px 25px;
      border: 2px solid #333;
      font-size: 13px;
      font-weight: bold;
      text-align: center;
    }

    .offset-none { outline: 3px solid #3498db; }
    .offset-3 { outline: 3px solid #3498db; outline-offset: 3px; }
    .offset-6 { outline: 3px solid #3498db; outline-offset: 6px; }
    .offset-neg { outline: 3px solid #e74c3c; outline-offset: -3px; }

    /* === Focus States === */
    .form-demo {
      display: flex;
      flex-direction: column;
      gap: 15px;
      max-width: 400px;
    }

    .input-default {
      padding: 10px 12px;
      border: 2px solid #ddd;
      border-radius: 6px;
      font-size: 14px;
    }

    .input-default:focus {
      outline: 3px solid #3498db;
      outline-offset: 2px;
      border-color: #3498db;
    }

    .input-success:focus {
      outline: 3px solid #2ecc71;
      outline-offset: 2px;
      border-color: #2ecc71;
    }

    .input-error:focus {
      outline: 3px solid #e74c3c;
      outline-offset: 2px;
      border-color: #e74c3c;
    }

    .btn-focus {
      padding: 10px 24px;
      border: 2px solid #3498db;
      background-color: white;
      color: #3498db;
      border-radius: 6px;
      font-size: 14px;
      font-weight: bold;
      cursor: pointer;
    }

    .btn-focus:focus {
      outline: 3px solid #3498db;
      outline-offset: 3px;
    }

    .btn-focus:active {
      outline-offset: 1px;
    }

    .label {
      font-size: 12px;
      color: #888;
      margin-top: 5px;
    }

    /* === Overflow Demo === */
    .overflow-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
      gap: 15px;
    }

    .overflow-box {
      height: 120px;
      background-color: #f8f9fa;
      border: 2px solid #ddd;
      border-radius: 6px;
      padding: 12px;
      font-size: 13px;
      line-height: 1.6;
      color: #555;
    }

    .overflow-visible {
      overflow: visible;
    }

    .overflow-hidden {
      overflow: hidden;
    }

    .overflow-scroll {
      overflow: scroll;
    }

    .overflow-auto {
      overflow: auto;
    }

    .overflow-label {
      font-size: 11px;
      color: #888;
      text-align: center;
      margin-top: 8px;
      font-weight: bold;
    }

    /* === Overflow X/Y === */
    .overflow-xy-grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 15px;
    }

    .overflow-xy-box {
      background-color: #f8f9fa;
      border: 2px solid #ddd;
      border-radius: 6px;
      padding: 12px;
      font-size: 13px;
    }

    .overflow-x-demo {
      overflow-x: auto;
      width: 200px;
      white-space: nowrap;
    }

    .overflow-y-demo {
      overflow-y: auto;
      height: 120px;
    }

    .long-text {
      white-space: nowrap;
      color: #555;
      font-size: 13px;
    }

    /* === Scrollable Container === */
    .scroll-container {
      max-height: 200px;
      overflow-y: auto;
      border: 2px solid #ddd;
      border-radius: 8px;
    }

    .scroll-item {
      padding: 12px 16px;
      border-bottom: 1px solid #eee;
      font-size: 14px;
      color: #555;
    }

    .scroll-item:nth-child(even) {
      background-color: #f9f9f9;
    }

    .scroll-item:last-child {
      border-bottom: none;
    }

    .scroll-header {
      padding: 12px 16px;
      background-color: #2c3e50;
      color: white;
      font-weight: bold;
      font-size: 14px;
      position: sticky;
      top: 0;
    }

    /* === Code Block Overflow === */
    .code-block {
      background-color: #2c3e50;
      color: #ecf0f1;
      padding: 16px;
      border-radius: 8px;
      overflow-x: auto;
      font-family: monospace;
      font-size: 13px;
      line-height: 1.6;
    }

    .code-block .long-line {
      white-space: nowrap;
      color: #3498db;
    }

    /* === Image Gallery Overflow === */
    .gallery-scroll {
      overflow-x: auto;
      white-space: nowrap;
      padding: 10px 0;
      border: 2px solid #ddd;
      border-radius: 8px;
    }

    .gallery-item {
      display: inline-block;
      width: 150px;
      height: 120px;
      margin: 0 8px;
      border-radius: 6px;
      background-color: #3498db;
      color: white;
      font-weight: bold;
      font-size: 14px;
      text-align: center;
      line-height: 120px;
    }

    .gallery-item:nth-child(2) { background-color: #e74c3c; }
    .gallery-item:nth-child(3) { background-color: #2ecc71; }
    .gallery-item:nth-child(4) { background-color: #f39c12; }
    .gallery-item:nth-child(5) { background-color: #9b59b6; }
    .gallery-item:nth-child(6) { background-color: #1abc9c; }
    .gallery-item:nth-child(7) { background-color: #e67e22; }
    .gallery-item:nth-child(8) { background-color: #34495e; }

    /* === Text Truncate === */
    .truncate-box {
      width: 300px;
      padding: 10px;
      border: 2px solid #ddd;
      border-radius: 6px;
      font-size: 14px;
      color: #555;
      margin-bottom: 10px;
    }

    .text-truncate {
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    .text-clamp {
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
      overflow: hidden;
    }
  </style>
</head>
<body>

  <h1>CSS Outline & Overflow</h1>

  <!-- Outline Styles -->
  <div class="section">
    <h2>Outline Style Types</h2>
    <p>Outline supports the same line styles as border:</p>
    <div class="outline-grid">
      <div class="outline-box outline-solid">solid</div>
      <div class="outline-box outline-dashed">dashed</div>
      <div class="outline-box outline-dotted">dotted</div>
      <div class="outline-box outline-double">double</div>
      <div class="outline-box outline-groove">groove</div>
      <div class="outline-box outline-ridge">ridge</div>
    </div>
  </div>

  <!-- Outline Offset -->
  <div class="section">
    <h2>Outline Offset</h2>
    <p>Offset determines the distance of the outline from the border. A negative value places the outline inside the border:</p>
    <div class="offset-grid">
      <div>
        <div class="offset-box offset-none">No offset</div>
        <div class="label">offset: 0</div>
      </div>
      <div>
        <div class="offset-box offset-3">Offset 3px</div>
        <div class="label">offset: 3px</div>
      </div>
      <div>
        <div class="offset-box offset-6">Offset 6px</div>
        <div class="label">offset: 6px</div>
      </div>
      <div>
        <div class="offset-box offset-neg">Offset -3px</div>
        <div class="label">offset: -3px (inside)</div>
      </div>
    </div>
  </div>

  <!-- Focus States -->
  <div class="section">
    <h2>Focus States — The Main Use of Outline</h2>
    <p>Outline is most often used for focus states. Click the input below to see the outline:</p>
    <div class="form-demo">
      <div>
        <input type="text" class="input-default" placeholder="Default input — Click me">
        <div class="label">outline: 3px solid #3498db</div>
      </div>
      <div>
        <input type="text" class="input-default input-success" placeholder="Success input — Click me" style="border-color: #2ecc71;">
        <div class="label">outline: 3px solid #2ecc71</div>
      </div>
      <div>
        <input type="text" class="input-default input-error" placeholder="Error input — Click me" style="border-color: #e74c3c;">
        <div class="label">outline: 3px solid #e74c3c</div>
      </div>
      <button class="btn-focus">Button with Focus Outline</button>
    </div>
  </div>

  <!-- Overflow Values -->
  <div class="section">
    <h2>Overflow Types</h2>
    <p>The four overflow values when content exceeds the element's size:</p>
    <div class="overflow-grid">
      <div>
        <div class="overflow-box overflow-visible">
          <strong>visible</strong><br>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
        </div>
        <div class="overflow-label">overflow: visible</div>
      </div>
      <div>
        <div class="overflow-box overflow-hidden">
          <strong>hidden</strong><br>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
        </div>
        <div class="overflow-label">overflow: hidden</div>
      </div>
      <div>
        <div class="overflow-box overflow-scroll">
          <strong>scroll</strong><br>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
        </div>
        <div class="overflow-label">overflow: scroll</div>
      </div>
      <div>
        <div class="overflow-box overflow-auto">
          <strong>auto</strong><br>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
        </div>
        <div class="overflow-label">overflow: auto</div>
      </div>
    </div>
  </div>

  <!-- Overflow X/Y -->
  <div class="section">
    <h2>Overflow X and Overflow Y</h2>
    <p>Controlling overflow separately for horizontal and vertical:</p>
    <div class="overflow-xy-grid">
      <div class="overflow-xy-box">
        <h3 style="font-size: 14px; margin-bottom: 10px;">overflow-x: auto</h3>
        <div class="overflow-x-demo">
          <span class="long-text">This very long text will have a horizontal scrollbar because overflow-x is set to auto.</span>
        </div>
      </div>
      <div class="overflow-xy-box">
        <h3 style="font-size: 14px; margin-bottom: 10px;">overflow-y: auto</h3>
        <div class="overflow-y-demo">
          <p>The first paragraph is long enough to create content that overflows vertically inside a container with a fixed height limit.</p>
          <p>The second paragraph will be in an area that can be scrolled vertically because overflow-y is set to auto.</p>
          <p>The third paragraph adds more content to make sure the scrollbar appears.</p>
          <p>The fourth paragraph ensures there is enough content to trigger a vertical scrollbar.</p>
        </div>
      </div>
    </div>
  </div>

  <!-- Scrollable Container -->
  <div class="section">
    <h2>Container Scrollable</h2>
    <p>A scrollable list with a sticky header:</p>
    <div class="scroll-container">
      <div class="scroll-header">CSS Course List</div>
      <div class="scroll-item">1. CSS Basic — Selector & Properties</div>
      <div class="scroll-item">2. Box Model — Margin, Padding, Border</div>
      <div class="scroll-item">3. Typography — Font & Text Styling</div>
      <div class="scroll-item">4. Colors & Background</div>
      <div class="scroll-item">5. Display Property</div>
      <div class="scroll-item">6. Position — Static, Relative, Absolute</div>
      <div class="scroll-item">7. Flexbox Layout</div>
      <div class="scroll-item">8. CSS Grid Layout</div>
      <div class="scroll-item">9. Responsive Design & Media Queries</div>
      <div class="scroll-item">10. CSS Animation & Transition</div>
      <div class="scroll-item">11. CSS Variables</div>
      <div class="scroll-item">12. Advanced Selectors</div>
    </div>
  </div>

  <!-- Code Block -->
  <div class="section">
    <h2>Code Block Overflow</h2>
    <p>Long code uses overflow-x: auto for a horizontal scrollbar:</p>
    <div class="code-block">
      <span class="long-line">const veryLongFunctionName = (parameterOne, parameterTwo, parameterThree, parameterFour) => { return parameterOne + parameterTwo + parameterThree + parameterFour; };</span>
    </div>
  </div>

  <!-- Gallery Scroll -->
  <div class="section">
    <h2>Horizontal Gallery Scroll</h2>
    <p>An image gallery that can be scrolled horizontally:</p>
    <div class="gallery-scroll">
      <div class="gallery-item">1</div>
      <div class="gallery-item">2</div>
      <div class="gallery-item">3</div>
      <div class="gallery-item">4</div>
      <div class="gallery-item">5</div>
      <div class="gallery-item">6</div>
      <div class="gallery-item">7</div>
      <div class="gallery-item">8</div>
    </div>
  </div>

  <!-- Text Truncation -->
  <div class="section">
    <h2>Text Truncation</h2>
    <p>Truncating overly long text with overflow:</p>
    <div class="truncate-box">
      <div class="text-truncate">
        This is a very long text that will be cut off with an ellipsis (...) because it uses text-overflow: ellipsis
      </div>
    </div>
    <div class="label" style="margin-bottom: 15px;">white-space: nowrap + overflow: hidden + text-overflow: ellipsis</div>

    <div class="truncate-box">
      <div class="text-clamp">
        This is a very long text that will be cut off after two lines using the line-clamp technique. This technique leverages webkit properties to set a limit on the number of lines in the text.
      </div>
    </div>
    <div class="label">-webkit-line-clamp: 2 (max 2 lines)</div>
  </div>

</body>
</html>

Code Explanation

  1. Outline Styles — Six boxes with different outline types: solid, dashed, dotted, double, groove, and ridge. The outline sits outside the border and does not affect the element's size.

  2. Outline Offset — Four boxes showing various offsets:

  3. 0 — Outline hugs the border
  4. 3px — Outline is 3px away from the border
  5. 6px — Outline is 6px away from the border
  6. -3px — Outline sits inside the border (negative offset)

  7. Focus States — Form inputs with three states: default (blue), success (green), and error (red). The button also has a focus state with an outline offset.

  8. Overflow Values — Four boxes showing the differences between overflow values:

  9. visible — Content overflows and is visible outside the element
  10. hidden — Overflowing content is clipped
  11. scroll — A scrollbar always appears even if content does not overflow
  12. auto — A scrollbar only appears if content overflows

  13. Overflow X/Y — A demonstration of horizontal and vertical overflow controlled separately.

  14. Scrollable Container — A course list with overflow-y: auto and a sticky header.

  15. Code Block — A code block with overflow-x: auto to handle long lines of code.

  16. Gallery Scroll — A horizontal gallery with overflow-x: auto and white-space: nowrap.

  17. Text Truncation — Two techniques for cutting off text: text-overflow: ellipsis (one line) and -webkit-line-clamp: 2 (two lines).


Everyday Use Cases

<!DOCTYPE html>
<html lang="en">
<head>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }

    body {
      font-family: Arial, sans-serif;
      background-color: #f5f5f5;
      color: #333;
    }

    /* === Accessible Form with Focus States === */
    .form-section {
      max-width: 500px;
      margin: 30px auto;
      padding: 30px;
      background-color: white;
      border-radius: 8px;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    }

    .form-section h2 {
      font-size: 20px;
      margin-bottom: 20px;
      color: #2c3e50;
    }

    .form-group {
      margin-bottom: 18px;
    }

    .form-group label {
      display: block;
      margin-bottom: 6px;
      font-size: 14px;
      font-weight: bold;
      color: #333;
    }

    .form-group input,
    .form-group textarea {
      width: 100%;
      padding: 10px 12px;
      border: 2px solid #ddd;
      border-radius: 6px;
      font-size: 14px;
      transition: all 0.2s;
    }

    .form-group input:focus,
    .form-group textarea:focus {
      outline: 3px solid rgba(52, 152, 219, 0.3);
      outline-offset: 2px;
      border-color: #3498db;
    }

    .form-group textarea {
      height: 100px;
      resize: vertical;
      overflow-y: auto;
    }

    .form-group input::placeholder,
    .form-group textarea::placeholder {
      color: #bbb;
    }

    .form-actions {
      display: flex;
      gap: 10px;
    }

    .btn-submit {
      padding: 10px 24px;
      background-color: #3498db;
      color: white;
      border: none;
      border-radius: 6px;
      font-size: 14px;
      font-weight: bold;
      cursor: pointer;
    }

    .btn-submit:focus {
      outline: 3px solid rgba(52, 152, 219, 0.4);
      outline-offset: 3px;
    }

    .btn-cancel {
      padding: 10px 24px;
      background-color: transparent;
      color: #666;
      border: 2px solid #ddd;
      border-radius: 6px;
      font-size: 14px;
      cursor: pointer;
    }

    .btn-cancel:focus {
      outline: 3px solid rgba(0, 0, 0, 0.1);
      outline-offset: 2px;
    }

    /* === Chat Interface === */
    .chat-container {
      max-width: 400px;
      margin: 30px auto;
      background-color: white;
      border-radius: 8px;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
      overflow: hidden;
    }

    .chat-header {
      padding: 15px;
      background-color: #2c3e50;
      color: white;
      font-weight: bold;
    }

    .chat-messages {
      height: 300px;
      overflow-y: auto;
      padding: 15px;
      background-color: #f5f5f5;
    }

    .chat-message {
      margin-bottom: 12px;
      display: flex;
    }

    .chat-bubble {
      max-width: 80%;
      padding: 10px 14px;
      border-radius: 12px;
      font-size: 14px;
      line-height: 1.4;
    }

    .chat-bubble.incoming {
      background-color: white;
      border: 1px solid #ddd;
      border-bottom-left-radius: 2px;
    }

    .chat-bubble.outgoing {
      background-color: #3498db;
      color: white;
      margin-left: auto;
      border-bottom-right-radius: 2px;
    }

    .chat-input {
      display: flex;
      padding: 10px;
      border-top: 1px solid #eee;
      background-color: white;
    }

    .chat-input input {
      flex: 1;
      padding: 8px 12px;
      border: 2px solid #ddd;
      border-radius: 20px;
      font-size: 14px;
      outline: none;
    }

    .chat-input input:focus {
      border-color: #3498db;
      outline: 2px solid rgba(52, 152, 219, 0.2);
      outline-offset: 1px;
    }

    .chat-send {
      margin-left: 8px;
      padding: 8px 16px;
      background-color: #3498db;
      color: white;
      border: none;
      border-radius: 20px;
      cursor: pointer;
      font-weight: bold;
    }
  </style>
</head>
<body>

  <!-- Accessible Form -->
  <div class="form-section">
    <h2>Form with Focus States</h2>
    <div class="form-group">
      <label for="name">Full Name</label>
      <input type="text" id="name" placeholder="Enter your name">
    </div>
    <div class="form-group">
      <label for="email">Email</label>
      <input type="email" id="email" placeholder="Enter your email">
    </div>
    <div class="form-group">
      <label for="message">Message</label>
      <textarea id="message" placeholder="Write your message..."></textarea>
    </div>
    <div class="form-actions">
      <button class="btn-submit">Send</button>
      <button class="btn-cancel">Cancel</button>
    </div>
  </div>

  <!-- Chat Interface -->
  <div class="chat-container">
    <div class="chat-header">Chat Support</div>
    <div class="chat-messages">
      <div class="chat-message">
        <div class="chat-bubble incoming">Hello! Is there anything I can help you with?</div>
      </div>
      <div class="chat-message">
        <div class="chat-bubble outgoing">I need help with CSS layout</div>
      </div>
      <div class="chat-message">
        <div class="chat-bubble incoming">Of course! Have you tried using Flexbox or CSS Grid yet?</div>
      </div>
      <div class="chat-message">
        <div class="chat-bubble outgoing">Not yet, I'm still new to CSS</div>
      </div>
      <div class="chat-message">
        <div class="chat-bubble incoming">No problem! Start with Flexbox first. Flexbox is easier to understand for one-dimensional layouts.</div>
      </div>
      <div class="chat-message">
        <div class="chat-bubble outgoing">Okay, I'll give it a try. Thank you!</div>
      </div>
    </div>
    <div class="chat-input">
      <input type="text" placeholder="Type a message...">
      <button class="chat-send">Send</button>
    </div>
  </div>

</body>
</html>

In the example above:
- Form — Inputs with a soft outline (rgba) for an elegant focus state that is not too thick or distracting
- Chat Interface — A chat container with overflow-y: auto on the message area, and an input with a subtle outline-offset when focused


Accessibility Tips

Never use outline: none without providing an alternative focus indicator. The outline is an important accessibility indicator for keyboard users.

/* ❌ Bad — Removes the focus indicator */
*:focus {
  outline: none;
}

/* ✅ Good — Replaces it with an alternative focus indicator */
*:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.5);
}

Conclusion

Outline:
- Outline is a line outside the border that takes up no space
- Most often used for focus states on interactive elements
- outline-offset controls the distance of the outline from the border (negative value = inside)
- Different from a border: outline does not follow border-radius and cannot be set per side

Overflow:
- visible (default) — Content is displayed outside the element
- hidden — Overflowing content is clipped
- scroll — A scrollbar always appears
- auto — A scrollbar appears only when content overflows
- overflow-x and overflow-y control overflow per axis
- Text truncation techniques: text-overflow: ellipsis for one line, -webkit-line-clamp for multiple lines