CSS3 & Responsive Design

Borders, Border-Radius & Outlines

25 min Lesson 15 of 60

Understanding CSS Borders

Borders are one of the most fundamental visual properties in CSS. Every HTML element can have a border around it, and CSS gives you complete control over that border's width, style, color, and shape. Borders serve both functional and decorative purposes -- they can separate content sections, highlight interactive elements, create visual hierarchy, and even produce complex shapes without any images. In this lesson, we will explore every aspect of CSS borders, from the basic shorthand syntax to advanced techniques like border-image and CSS triangles.

A border sits between an element's padding and its margin in the CSS box model. This means the border is drawn outside the padding area but inside the margin area. The border's width contributes to the element's total size unless you are using box-sizing: border-box, in which case the border width is included within the declared width and height.

The Border Shorthand Property

The border shorthand property is the most common way to declare borders. It allows you to set the width, style, and color in a single declaration. The order of values does not strictly matter, but the conventional order is width, style, then color.

Border Shorthand Syntax

/* Shorthand: width style color */
.element {
    border: 2px solid #333333;
}

/* Equivalent longhand properties */
.element {
    border-width: 2px;
    border-style: solid;
    border-color: #333333;
}

/* Only style is required -- width defaults to medium, color defaults to currentColor */
.minimal-border {
    border: solid;
}

/* Various shorthand examples */
.thin-dashed {
    border: 1px dashed #999;
}

.thick-double {
    border: 4px double darkblue;
}

.red-dotted {
    border: 3px dotted crimson;
}
Note: The only required value in the border shorthand is the border-style. If you omit the width, it defaults to medium (typically 3px). If you omit the color, it defaults to currentColor, which means it inherits the element's text color. This is actually a very useful default because it means borders automatically match your text color.

Border Width

The border-width property controls the thickness of the border. You can set it using specific length values or keyword values. Like margin and padding, you can specify different widths for each side using one, two, three, or four values.

Border Width Values

/* Keyword values */
.thin-border {
    border-style: solid;
    border-width: thin;      /* Typically 1px */
}

.medium-border {
    border-style: solid;
    border-width: medium;    /* Typically 3px -- this is the default */
}

.thick-border {
    border-style: solid;
    border-width: thick;     /* Typically 5px */
}

/* Specific length values */
.custom-border {
    border-style: solid;
    border-width: 2px;
}

.em-border {
    border-style: solid;
    border-width: 0.1em;     /* Relative to font-size */
}

/* Multiple values (top, right, bottom, left -- clockwise) */
.varied-widths {
    border-style: solid;
    border-width: 1px 2px 3px 4px;  /* top right bottom left */
}

/* Two values: top/bottom and left/right */
.two-values {
    border-style: solid;
    border-width: 1px 3px;   /* top/bottom: 1px, left/right: 3px */
}

/* Three values: top, left/right, bottom */
.three-values {
    border-style: solid;
    border-width: 1px 2px 3px;  /* top: 1px, left/right: 2px, bottom: 3px */
}

/* Individual side widths */
.individual-widths {
    border-style: solid;
    border-top-width: 5px;
    border-right-width: 2px;
    border-bottom-width: 5px;
    border-left-width: 2px;
}
Tip: While keyword values (thin, medium, thick) are valid, their exact pixel values are not strictly defined in the CSS specification and can vary slightly between browsers. For consistent results across all browsers, always use specific pixel values like 1px, 2px, or 3px instead of keyword values.

Border Style

The border-style property is the most critical border property because no border will be displayed unless a style is set. CSS provides ten different border style values, each creating a distinct visual effect. Some of them are decorative and rarely used in modern design, but understanding all of them gives you a complete toolkit.

All Border Style Values

/* No border (default) */
.no-border {
    border-style: none;
}

/* Hidden -- same as none but wins in border-collapse table conflicts */
.hidden-border {
    border-style: hidden;
}

/* Solid -- the most common, a single continuous line */
.solid-border {
    border: 3px solid #333;
}

/* Dashed -- a series of short line segments */
.dashed-border {
    border: 3px dashed #333;
}

/* Dotted -- a series of dots */
.dotted-border {
    border: 3px dotted #333;
}

/* Double -- two parallel solid lines with space between */
/* The border-width must be at least 3px for both lines to show */
.double-border {
    border: 5px double #333;
}

/* Groove -- carved effect, looks like it is etched into the page */
.groove-border {
    border: 5px groove #888;
}

/* Ridge -- opposite of groove, looks like it is raised from the page */
.ridge-border {
    border: 5px ridge #888;
}

/* Inset -- makes the box look like it is embedded into the page */
.inset-border {
    border: 5px inset #888;
}

/* Outset -- makes the box look like it is raised from the page */
.outset-border {
    border: 5px outset #888;
}

/* Mixed styles on different sides */
.mixed-styles {
    border-top-style: solid;
    border-right-style: dashed;
    border-bottom-style: dotted;
    border-left-style: double;
    border-width: 4px;
    border-color: #333;
}
Note: The difference between none and hidden only matters in the context of collapsing table borders (border-collapse: collapse). When table borders are collapsing, hidden takes priority over all other border styles, while none has the lowest priority. In all other contexts, they behave identically.

Border Color

The border-color property accepts any valid CSS color value -- hex codes, RGB, RGBA, HSL, HSLA, named colors, or the special keyword currentColor. Like width and style, you can specify different colors for each side.

Border Color Examples

/* Single color for all sides */
.uniform-color {
    border: 3px solid;
    border-color: #3498db;
}

/* Different colors per side */
.colorful-border {
    border: 3px solid;
    border-color: red green blue orange;
    /* top: red, right: green, bottom: blue, left: orange */
}

/* Using currentColor (default behavior) */
.inherit-text-color {
    color: navy;
    border: 2px solid;
    /* Border will be navy because currentColor is the default */
}

/* Semi-transparent borders */
.transparent-border {
    border: 3px solid rgba(0, 0, 0, 0.3);
}

/* Individual side colors */
.custom-side-colors {
    border: 3px solid;
    border-top-color: #e74c3c;
    border-right-color: #3498db;
    border-bottom-color: #2ecc71;
    border-left-color: #f39c12;
}

Individual Side Borders

CSS provides shorthand properties for each individual side of the border. These are extremely useful when you want a border on only one or two sides, or when you need different styles on different sides. Each side shorthand accepts the same values as the main border shorthand -- width, style, and color.

Individual Side Border Properties

/* Border only on the bottom -- common for underline effects */
.bottom-only {
    border: none;
    border-bottom: 2px solid #333;
}

/* Left accent border -- common for blockquotes and callouts */
.left-accent {
    border-left: 4px solid #3498db;
    padding-left: 16px;
}

/* Top and bottom borders -- horizontal rule effect */
.top-bottom {
    border-top: 1px solid #ddd;
    border-bottom: 1px solid #ddd;
    padding: 16px 0;
}

/* Custom card with different side treatments */
.fancy-card {
    border-top: 4px solid #e74c3c;
    border-right: 1px solid #eee;
    border-bottom: 1px solid #ddd;
    border-left: 1px solid #eee;
    padding: 20px;
}

/* Navigation tab -- active state */
.nav-tab-active {
    border: 1px solid #ddd;
    border-bottom: none;
    border-top: 3px solid #3498db;
    padding: 10px 20px;
    background: white;
}

/* Individual side longhand properties */
.detailed-sides {
    border-top-width: 2px;
    border-top-style: solid;
    border-top-color: red;

    border-right-width: 3px;
    border-right-style: dashed;
    border-right-color: blue;

    border-bottom-width: 2px;
    border-bottom-style: solid;
    border-bottom-color: green;

    border-left-width: 3px;
    border-left-style: dashed;
    border-left-color: orange;
}
Tip: A very common design pattern is the left-accent border, used for callout boxes, blockquotes, and notification messages. A thick colored left border with some left padding creates a clean visual indicator that draws attention without being overwhelming. Many popular CSS frameworks use this pattern extensively.

Border Radius: Rounding Corners

The border-radius property is one of the most beloved CSS3 additions. Before CSS3, creating rounded corners required images or complex workarounds. Now, a single property rounds any element's corners. Despite its name, border-radius works on elements even without a visible border -- it clips the element's background and content to the rounded shape.

Border Radius Basics

/* Single value -- all four corners the same */
.rounded {
    border-radius: 8px;
}

/* Two values -- top-left/bottom-right and top-right/bottom-left */
.diagonal-round {
    border-radius: 10px 0px;
    /* top-left & bottom-right: 10px, top-right & bottom-left: 0px */
}

/* Three values -- top-left, top-right/bottom-left, bottom-right */
.three-corners {
    border-radius: 10px 5px 20px;
}

/* Four values -- top-left, top-right, bottom-right, bottom-left (clockwise) */
.four-corners {
    border-radius: 10px 5px 20px 0px;
}

/* Individual corner properties */
.individual-corners {
    border-top-left-radius: 10px;
    border-top-right-radius: 20px;
    border-bottom-right-radius: 10px;
    border-bottom-left-radius: 20px;
}

/* Percentage values -- relative to the element's dimensions */
.percentage-radius {
    border-radius: 10%;
}

/* Using em values for scalable corners */
.scalable-radius {
    border-radius: 0.5em;
}

Creating Circles and Pills

By using large border-radius values or the 50% trick, you can create perfect circles and pill shapes. These are extremely common in modern web design for avatars, badges, tags, and buttons.

Circles and Pill Shapes

/* Perfect circle -- element must be square (equal width and height) */
.circle {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background: #3498db;
}

/* Avatar circle with image */
.avatar {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    overflow: hidden;           /* Clips the image to the circle */
    border: 3px solid white;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;          /* Ensures image fills the circle */
}

/* Pill shape -- use a very large border-radius on a rectangular element */
.pill {
    display: inline-block;
    padding: 6px 20px;
    border-radius: 9999px;      /* Any very large value works */
    background: #e74c3c;
    color: white;
    font-size: 14px;
}

/* Badge / tag */
.badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 12px;
    background: #2ecc71;
    color: white;
    font-size: 12px;
    font-weight: bold;
}

/* Rounded button */
.btn-rounded {
    display: inline-block;
    padding: 12px 32px;
    border: none;
    border-radius: 25px;
    background: #3498db;
    color: white;
    font-size: 16px;
    cursor: pointer;
}

/* Semi-circle -- round only the top */
.semi-circle {
    width: 100px;
    height: 50px;
    border-radius: 50px 50px 0 0;
    background: #9b59b6;
}
Note: Using border-radius: 50% to create a circle only works when the element has equal width and height (a square). If the element is rectangular, 50% will create an ellipse instead. For pill shapes, use a very large fixed value like 9999px or 100vw instead of 50% -- this guarantees the ends are fully rounded regardless of the element's dimensions.

Elliptical (Asymmetric) Border Radius

Each corner of border-radius actually accepts two values -- a horizontal radius and a vertical radius. When these two values are different, the corner forms an elliptical curve instead of a circular one. You separate the horizontal and vertical radii with a forward slash (/) in the shorthand syntax.

Elliptical Border Radius

/* Elliptical corners: horizontal-radii / vertical-radii */
.elliptical {
    border-radius: 50px / 25px;
    /* All corners: 50px horizontal, 25px vertical */
}

/* Different horizontal and vertical per corner */
.complex-shape {
    border-radius: 10px 20px 30px 40px / 40px 30px 20px 10px;
    /* Horizontal: TL=10, TR=20, BR=30, BL=40 */
    /* Vertical:   TL=40, TR=30, BR=20, BL=10 */
}

/* Egg shape */
.egg {
    width: 120px;
    height: 160px;
    border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
    background: #f5deb3;
}

/* Organic blob shape */
.blob {
    width: 200px;
    height: 200px;
    border-radius: 30% 70% 70% 30% / 30% 30% 70% 70%;
    background: linear-gradient(135deg, #667eea, #764ba2);
}

/* Individual elliptical corner */
.single-elliptical {
    border-top-left-radius: 50px 25px;
    /* 50px horizontal, 25px vertical for top-left only */
}

Border Image

The border-image property allows you to use an image or gradient as a border instead of a solid color. This is a powerful but less commonly used feature. The border-image property is a shorthand for five sub-properties: border-image-source, border-image-slice, border-image-width, border-image-outset, and border-image-repeat.

Border Image Examples

/* Gradient border */
.gradient-border {
    border: 4px solid transparent;
    border-image: linear-gradient(to right, #e74c3c, #3498db) 1;
}

/* Gradient border on all sides */
.full-gradient-border {
    border: 3px solid;
    border-image-source: linear-gradient(45deg, #ff6b6b, #feca57, #48dbfb, #ff9ff3);
    border-image-slice: 1;
}

/* Border image with an actual image */
.image-border {
    border: 30px solid transparent;
    border-image-source: url("border-pattern.png");
    border-image-slice: 30;
    border-image-repeat: round;
}

/* Border image sub-properties */
.detailed-border-image {
    border: 20px solid transparent;
    border-image-source: url("ornate-border.png");
    border-image-slice: 20 fill;  /* fill keeps the center of the image */
    border-image-width: 20px;
    border-image-outset: 5px;     /* Extends border beyond the border box */
    border-image-repeat: stretch; /* stretch, repeat, round, space */
}

/* Rainbow gradient border on bottom only */
.rainbow-underline {
    border-bottom: 3px solid transparent;
    border-image: linear-gradient(to right, red, orange, yellow, green, blue, purple) 1;
    border-image-slice: 0 0 1 0; /* Only bottom slice */
}
Warning: When using border-image, the border-radius property is ignored. The border image will always render with sharp corners. If you need a gradient border with rounded corners, you will need to use a workaround such as a background gradient on a wrapper element or a pseudo-element technique. This is a long-standing CSS limitation.

Outlines vs Borders

CSS outlines look similar to borders but behave very differently. Understanding the differences between outlines and borders is important for both design and accessibility. The outline property draws a line around an element outside the border, but unlike borders, outlines do not take up space in the layout and do not affect the element's dimensions or position.

Outline Properties

/* Outline shorthand -- similar to border shorthand */
.outlined {
    outline: 2px solid #3498db;
}

/* Outline individual properties */
.detailed-outline {
    outline-width: 3px;
    outline-style: dashed;
    outline-color: red;
}

/* Outline offset -- creates space between the border/edge and the outline */
.offset-outline {
    border: 2px solid #333;
    outline: 2px solid #3498db;
    outline-offset: 4px;       /* 4px gap between border and outline */
}

/* Negative outline offset -- outline moves inside the element */
.inward-outline {
    outline: 2px dashed red;
    outline-offset: -10px;
}

/* Removing outlines (be careful with accessibility!) */
.no-outline {
    outline: none;
}

/* Custom focus outline for accessibility */
button:focus-visible {
    outline: 3px solid #3498db;
    outline-offset: 2px;
}

/* Double ring effect with border + outline */
.double-ring {
    border: 3px solid #e74c3c;
    outline: 3px solid #3498db;
    outline-offset: 3px;
}

Key Differences Between Borders and Outlines

There are several important differences between borders and outlines that every developer should understand:

  • Layout impact -- Borders are part of the box model and affect element dimensions. Outlines do not take up space and do not affect layout. Adding an outline will never cause other elements to shift.
  • Individual sides -- Borders can be set independently per side (top, right, bottom, left). Outlines always wrap the entire element uniformly -- you cannot have an outline on only one side.
  • Border-radius -- Borders respect border-radius and follow the rounded shape. In modern browsers, outlines also follow border-radius, but this was not always the case in older browsers.
  • Offset -- Outlines have the outline-offset property to create space between the outline and the element. Borders have no equivalent offset property.
  • Overlap -- Because outlines do not affect layout, they can overlap adjacent elements. This can be desirable (for focus indicators) or problematic (for decorative purposes).
  • Accessibility -- Outlines are the default way browsers indicate keyboard focus on interactive elements. Removing outlines without providing an alternative focus indicator is a serious accessibility violation.

Outlines for Accessibility

One of the most important uses of outlines is for keyboard navigation focus indicators. When users navigate a website using the Tab key, the browser shows an outline around the currently focused element. This is essential for users who cannot use a mouse -- those with motor disabilities, vision impairments, or anyone who prefers keyboard navigation.

Accessible Focus Styles

/* NEVER do this without providing an alternative! */
/* This removes the focus indicator for ALL users */
*:focus {
    outline: none; /* ACCESSIBILITY VIOLATION */
}

/* Better: Use :focus-visible to only hide outlines for mouse users */
/* :focus-visible only matches when the browser determines focus should be visible */
button:focus {
    outline: none; /* Remove default for all focus */
}

button:focus-visible {
    outline: 3px solid #3498db; /* Show only for keyboard focus */
    outline-offset: 2px;
}

/* Best practice: Custom focus styles that match your design */
a:focus-visible {
    outline: 2px solid #e74c3c;
    outline-offset: 3px;
    border-radius: 3px;
}

input:focus-visible {
    outline: none;
    border-color: #3498db;
    box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.3);
}

/* High contrast focus for maximum visibility */
.high-contrast-focus:focus-visible {
    outline: 3px solid black;
    outline-offset: 2px;
    box-shadow: 0 0 0 6px white, 0 0 0 9px black;
}
Warning: Never remove focus outlines globally with *:focus { outline: none; } or a:focus { outline: 0; } without providing a clear visible alternative. This is one of the most common accessibility violations on the web. The :focus-visible pseudo-class is the modern solution -- it only shows the focus indicator when the browser detects keyboard navigation, so mouse users will not see it but keyboard users will.

CSS Triangles with Borders

One of the most clever CSS tricks is creating triangles using only borders. This technique exploits the fact that when an element has zero width and height, the borders meet at diagonal lines, forming triangles. This is used extensively for tooltips, dropdown arrows, speech bubbles, and decorative elements.

CSS Triangles

/* Basic triangle pointing up */
.triangle-up {
    width: 0;
    height: 0;
    border-left: 25px solid transparent;
    border-right: 25px solid transparent;
    border-bottom: 40px solid #e74c3c;
}

/* Triangle pointing down */
.triangle-down {
    width: 0;
    height: 0;
    border-left: 25px solid transparent;
    border-right: 25px solid transparent;
    border-top: 40px solid #3498db;
}

/* Triangle pointing right */
.triangle-right {
    width: 0;
    height: 0;
    border-top: 25px solid transparent;
    border-bottom: 25px solid transparent;
    border-left: 40px solid #2ecc71;
}

/* Triangle pointing left */
.triangle-left {
    width: 0;
    height: 0;
    border-top: 25px solid transparent;
    border-bottom: 25px solid transparent;
    border-right: 40px solid #f39c12;
}

/* Tooltip with triangle arrow using pseudo-element */
.tooltip {
    position: relative;
    background: #333;
    color: white;
    padding: 10px 16px;
    border-radius: 6px;
    display: inline-block;
}

.tooltip::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 8px solid transparent;
    border-right: 8px solid transparent;
    border-top: 8px solid #333;
}

/* Speech bubble */
.speech-bubble {
    position: relative;
    background: #e8f4f8;
    border: 1px solid #b8daff;
    border-radius: 12px;
    padding: 16px;
    max-width: 300px;
}

.speech-bubble::after {
    content: "";
    position: absolute;
    bottom: -10px;
    left: 30px;
    width: 0;
    height: 0;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    border-top: 10px solid #e8f4f8;
}

.speech-bubble::before {
    content: "";
    position: absolute;
    bottom: -12px;
    left: 29px;
    width: 0;
    height: 0;
    border-left: 11px solid transparent;
    border-right: 11px solid transparent;
    border-top: 11px solid #b8daff;
}
Tip: The CSS triangle trick works because when borders meet at a corner, they form a diagonal line. By making the element's width and height zero and setting three borders to transparent while keeping one opaque, you isolate a single triangle. The opaque border's side determines the direction the triangle points -- a solid bottom border creates a triangle pointing up because the bottom border is the visible part.

Practical Examples

Now let's combine everything we have learned into practical components that you would use in real-world projects.

Complete Card Component

<!-- HTML -->
<div class="card">
    <div class="card-image">
        <img src="photo.jpg" alt="Card image">
    </div>
    <div class="card-body">
        <span class="card-badge">Featured</span>
        <h3 class="card-title">Card Title</h3>
        <p class="card-text">Some descriptive text for this card.</p>
        <button class="card-btn">Learn More</button>
    </div>
</div>

<!-- CSS -->
<style>
.card {
    border: 1px solid #e0e0e0;
    border-radius: 12px;
    overflow: hidden;
    max-width: 350px;
    transition: border-color 0.3s ease;
}

.card:hover {
    border-color: #3498db;
}

.card-image img {
    width: 100%;
    display: block;
}

.card-body {
    padding: 20px;
}

.card-badge {
    display: inline-block;
    padding: 3px 12px;
    border-radius: 9999px;
    background: #e8f4f8;
    border: 1px solid #3498db;
    color: #3498db;
    font-size: 12px;
    font-weight: 600;
}

.card-title {
    margin: 12px 0 8px;
    font-size: 20px;
    border-bottom: 2px solid #f0f0f0;
    padding-bottom: 8px;
}

.card-btn {
    display: inline-block;
    padding: 10px 24px;
    border: 2px solid #3498db;
    border-radius: 6px;
    background: transparent;
    color: #3498db;
    cursor: pointer;
    transition: all 0.3s ease;
}

.card-btn:hover {
    background: #3498db;
    color: white;
}
</style>

Notification / Alert Messages

.alert {
    padding: 16px 20px;
    border-radius: 8px;
    border: 1px solid;
    border-left-width: 5px;
    margin-bottom: 16px;
}

.alert-success {
    background: #d4edda;
    border-color: #28a745;
    color: #155724;
}

.alert-warning {
    background: #fff3cd;
    border-color: #ffc107;
    color: #856404;
}

.alert-danger {
    background: #f8d7da;
    border-color: #dc3545;
    color: #721c24;
}

.alert-info {
    background: #d1ecf1;
    border-color: #17a2b8;
    color: #0c5460;
}

Avatar Circles with Status Indicators

<div class="avatar-wrapper">
    <img src="user.jpg" alt="User" class="avatar-circle">
    <span class="status-dot online"></span>
</div>

<style>
.avatar-wrapper {
    position: relative;
    display: inline-block;
}

.avatar-circle {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    border: 3px solid white;
    outline: 2px solid #e0e0e0;
    object-fit: cover;
}

.status-dot {
    position: absolute;
    bottom: 2px;
    right: 2px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 3px solid white;
}

.status-dot.online {
    background: #2ecc71;
}

.status-dot.offline {
    background: #95a5a6;
}

.status-dot.busy {
    background: #e74c3c;
}
</style>

Button Styles with Border Variations

/* Outlined / Ghost button */
.btn-outline {
    padding: 10px 24px;
    background: transparent;
    border: 2px solid #3498db;
    border-radius: 6px;
    color: #3498db;
    cursor: pointer;
    transition: all 0.2s ease;
}

.btn-outline:hover {
    background: #3498db;
    color: white;
}

/* Gradient border button */
.btn-gradient-border {
    padding: 10px 24px;
    background: white;
    border: 3px solid transparent;
    border-image: linear-gradient(135deg, #667eea, #764ba2) 1;
    color: #764ba2;
    cursor: pointer;
    font-weight: bold;
}

/* Animated underline button */
.btn-underline {
    padding: 10px 4px;
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    color: #333;
    cursor: pointer;
    transition: border-color 0.3s ease;
}

.btn-underline:hover {
    border-bottom-color: #e74c3c;
}

/* Pill button group */
.btn-group .btn-pill {
    padding: 8px 20px;
    border: 1px solid #ddd;
    background: white;
    cursor: pointer;
}

.btn-group .btn-pill:first-child {
    border-radius: 9999px 0 0 9999px;
}

.btn-group .btn-pill:last-child {
    border-radius: 0 9999px 9999px 0;
}

.btn-group .btn-pill.active {
    background: #3498db;
    border-color: #3498db;
    color: white;
}
Exercise 1: Create a user profile card component that includes:
  • A circular avatar image (80px by 80px) with a 3px white border and a colored outline
  • The card itself should have rounded corners (12px) with a subtle 1px border
  • A colored left accent border (4px) to indicate the user's role (e.g., green for admin, blue for member)
  • A pill-shaped role badge (e.g., "Admin", "Member") with a colored border matching the accent color
  • A hover effect that changes the card's border color
Exercise 2: Build a tooltip component using only CSS (no JavaScript). Create a container with a ::after pseudo-element that forms a triangle pointing downward. The tooltip should have rounded corners, a subtle border, and the triangle should be positioned at the bottom center. Then create variations where the triangle points up, left, and right.
Exercise 3: Create a set of four alert/notification boxes (success, warning, error, info) using the left-accent border pattern. Each should have a matching background color, a thick left border, rounded corners on the right side only, and appropriate text color. Add an icon area on the left side using a circular element with border-radius: 50%.