The Visual Building Blocks of Web Design
Welcome to our exploration of colors, backgrounds, and borders in CSS! These properties form the visual foundation of web design, allowing you to transform plain HTML documents into visually engaging experiences.
Today we'll learn how to implement colors effectively, create interesting backgrounds, and use borders to define and enhance elements. By mastering these properties, you'll be able to establish visual hierarchy, create coherent design systems, and craft interfaces that are both beautiful and functional.
File Organization
For today's session, we'll use the following files:
- CSS File:
styles/visual_elements.cssin your styles folder - HTML File:
visual_elements.htmlin your project root
Make sure to create these files and link them properly before we begin the exercises.
Color Theory for Web Developers
Before diving into CSS color implementation, let's explore some fundamental color theory concepts that will help you make informed design choices.
The Color Wheel and Relationships
The color wheel is a circular arrangement of colors based on their chromatic relationship:
- Primary colors: Red, blue, and yellow (in traditional color theory)
- Secondary colors: Green, orange, and purple (mixtures of primary colors)
- Tertiary colors: Mixtures of primary and secondary colors
Color Harmony Schemes
Color harmonies are structured ways to combine colors for pleasing visual effects:
- Monochromatic: Different shades, tints, and tones of a single color
- Analogous: Colors that are adjacent on the color wheel
- Complementary: Colors that are opposite each other on the color wheel
- Split-complementary: A color plus the two colors adjacent to its complement
- Triadic: Three colors equally spaced around the color wheel
- Tetradic: Four colors arranged in two complementary pairs
Color Psychology and Meaning
Colors evoke emotional and psychological responses that can vary by culture:
- Red: Energy, passion, danger, attention
- Blue: Trust, stability, calmness, professionalism
- Green: Growth, nature, health, wealth
- Yellow: Optimism, happiness, warning, energy
- Purple: Luxury, creativity, wisdom, sophistication
- Orange: Enthusiasm, creativity, determination
- Black: Elegance, power, mystery, formality
- White: Purity, cleanliness, simplicity, minimalism
- Gray: Neutrality, balance, sophistication
Real-world application: Notice how banks and financial institutions often use blue in their branding to convey trust and stability, while sale prices are frequently displayed in red to create urgency and capture attention.
Accessibility Considerations
When selecting colors, always consider accessibility for users with visual impairments:
- Color contrast: Ensure sufficient contrast between text and background colors (WCAG recommends a minimum contrast ratio of 4.5:1 for normal text)
- Color blindness: Don't rely solely on color to convey information (use additional visual cues)
- Text readability: Dark text on light backgrounds is typically most readable
Useful tools: Coolors for color scheme generation, WebAIM Contrast Checker for accessibility testing, and Adobe Color for exploring color harmonies.
Working with Colors in CSS
CSS offers multiple ways to specify colors, each with different advantages.
Color Notation Methods
Named Colors
CSS provides 140+ color keywords like red, blue, green, purple, etc.
/* Named color examples */
h1 {
color: navy;
}
.alert {
background-color: tomato;
}
.success-button {
background-color: limegreen;
}
Pros: Simple, intuitive, and human-readable
Cons: Limited selection, can't represent subtle variations
Best for: Prototyping, quick development, or when precise color matching isn't necessary
Hexadecimal (Hex) Colors
Six-digit codes preceded by a hash (#) that represent RGB values in base-16.
/* Hexadecimal color examples */
body {
background-color: #f5f5f5; /* Light gray */
}
h2 {
color: #333333; /* Dark gray */
}
.primary-button {
background-color: #0066cc; /* Blue */
}
Each pair of characters represents red, green, and blue values from 00 (none) to FF (maximum).
Shorthand: When each channel has repeated digits, you can use 3-digit shorthand:
#ff0000 → #f00 /* Red */
#00ff00 → #0f0 /* Green */
#0000ff → #00f /* Blue */
#ffffff → #fff /* White */
#000000 → #000 /* Black */
Pros: Precise, widely supported, compact
Cons: Not human-readable, difficult to modify by eye
Best for: Production code, exact color matching, design system implementation
RGB and RGBA Colors
Specifies red, green, and blue values on a scale of 0-255. RGBA adds an alpha channel for transparency (0-1).
/* RGB and RGBA examples */
.subtitle {
color: rgb(51, 51, 51); /* Dark gray */
}
.feature-box {
background-color: rgb(240, 240, 240); /* Light gray */
}
.overlay {
background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent black */
}
.tooltip {
background-color: rgba(0, 0, 0, 0.8); /* Nearly opaque black */
color: rgba(255, 255, 255, 0.9); /* Nearly opaque white */
}
Pros: Intuitive number scale, supports transparency with alpha channel
Cons: More verbose than hex codes
Best for: When transparency is needed, or when incrementally adjusting colors
HSL and HSLA Colors
Represents colors using Hue, Saturation, and Lightness. HSLA adds an alpha channel for transparency.
/* HSL and HSLA examples */
.brand-color {
color: hsl(204, 70%, 53%); /* Vibrant blue */
}
.muted-text {
color: hsl(0, 0%, 30%); /* Dark gray */
}
.highlight {
background-color: hsla(50, 100%, 50%, 0.2); /* Translucent yellow */
}
- Hue: Color in degrees around the color wheel (0° or 360° is red, 120° is green, 240° is blue)
- Saturation: Intensity of the color (0% is grayscale, 100% is full color)
- Lightness: Brightness of the color (0% is black, 100% is white, 50% is normal)
- Alpha: Transparency (0 is fully transparent, 1 is fully opaque)
Pros: Intuitive for creating variations, easier to adjust visually
Cons: Less commonly used, longer syntax
Best for: Creating color variations, theming, and situations where you need to adjust specific aspects of a color
Modern Color Functions in CSS
CSS Color Module Level 4 introduces new color functions with enhanced capabilities:
/* Modern RGB syntax with alpha */
.element {
color: rgb(51 51 51 / 0.8); /* RGB with alpha, space-separated */
}
/* Modern HSL syntax with alpha */
.element {
color: hsl(204 70% 53% / 0.5); /* HSL with alpha, space-separated */
}
/* Color manipulation with relative adjustments */
.darker-element {
color: hsl(from var(--brand-color) h s calc(l - 10%));
}
Note: These newer color functions might not be supported in all browsers yet, so check compatibility before using in production.
Applying Colors in Web Design
Let's explore how to effectively apply colors to different elements in your web pages.
Text Colors
The color property sets the color of text content and text decorations.
/* Text color examples */
body {
color: #333; /* Base text color for the entire document */
}
h1, h2, h3, h4, h5, h6 {
color: #222; /* Slightly darker color for headings */
}
a {
color: #0066cc; /* Blue for links */
}
a:hover {
color: #004499; /* Darker blue on hover */
}
.secondary-text {
color: #666; /* Lighter color for less important text */
}
.subtle-text {
color: rgba(0, 0, 0, 0.6); /* Semi-transparent black for even less emphasis */
}
.error-message {
color: #cc0000; /* Red for errors */
}
Background Colors
The background-color property sets the background color of elements.
/* Background color examples */
body {
background-color: #f9f9f9; /* Light gray background for the entire page */
}
header {
background-color: #333; /* Dark background for the header */
color: white; /* Light text on dark background */
}
.card {
background-color: white; /* White background for card components */
border: 1px solid #ddd;
}
.primary-button {
background-color: #0066cc; /* Blue background for primary buttons */
color: white;
}
.primary-button:hover {
background-color: #0055aa; /* Darker blue on hover */
}
.tag {
background-color: rgba(0, 102, 204, 0.1); /* Translucent blue for tags */
color: #0066cc; /* Blue text that matches the background hue */
}
Creating Color Systems
Establish a consistent color system with clear roles for each color:
/* Modern approach using CSS custom properties (variables) */
:root {
/* Primary colors */
--color-primary: #0066cc;
--color-primary-light: #4d94ff;
--color-primary-dark: #004c99;
/* Secondary colors */
--color-secondary: #6c757d;
--color-secondary-light: #868e96;
--color-secondary-dark: #495057;
/* Semantic colors */
--color-success: #28a745;
--color-warning: #ffc107;
--color-danger: #dc3545;
--color-info: #17a2b8;
/* Neutral colors */
--color-text: #333333;
--color-text-light: #666666;
--color-text-lighter: #999999;
--color-background: #f8f9fa;
--color-border: #dee2e6;
}
/* Using the color system */
.button-primary {
background-color: var(--color-primary);
color: white;
}
.button-primary:hover {
background-color: var(--color-primary-dark);
}
.alert-success {
background-color: var(--color-success);
color: white;
}
.section-border {
border: 1px solid var(--color-border);
}
Real-world example: Large websites and applications like Facebook, Twitter, and Google all use carefully planned color systems. Notice how they apply a consistent primary brand color across interactive elements, while using variations for hover states, highlights, and supporting elements.
Color Consistency Techniques
Methods to ensure color consistency throughout your site:
- CSS variables: Define colors once and reference them throughout your stylesheet
- Sass/SCSS variables: If using a preprocessor, define colors as variables
- Systematic variations: Create consistent rules for hover states, active states, etc.
- Utility classes: Create reusable color classes for common patterns
/* Utility class example */
.text-primary { color: var(--color-primary); }
.text-success { color: var(--color-success); }
.text-warning { color: var(--color-warning); }
.text-danger { color: var(--color-danger); }
.bg-primary { background-color: var(--color-primary); }
.bg-success { background-color: var(--color-success); }
.bg-warning { background-color: var(--color-warning); }
.bg-danger { background-color: var(--color-danger); }
Beyond Basic Backgrounds
While background colors are essential, CSS offers much more sophisticated background capabilities.
Background Images
The background-image property sets an image as the background of an element.
/* Basic background image */
.hero-section {
background-image: url('/images/hero-background.jpg');
}
Background Properties
Several properties control how background images display:
background-size
/* Background size examples */
.cover-bg {
background-image: url('/images/landscape.jpg');
background-size: cover; /* Cover the entire element, maintaining aspect ratio */
}
.contain-bg {
background-image: url('/images/icon.png');
background-size: contain; /* Fit the entire image inside the element */
}
.custom-size-bg {
background-image: url('/images/pattern.jpg');
background-size: 200px 100px; /* Specific width and height */
}
.percentage-bg {
background-image: url('/images/texture.jpg');
background-size: 50% auto; /* 50% width, auto height */
}
background-position
/* Background position examples */
.centered-bg {
background-image: url('/images/logo.png');
background-position: center; /* Center the image */
}
.bottom-right-bg {
background-image: url('/images/watermark.png');
background-position: bottom right; /* Position at bottom right */
}
.custom-position-bg {
background-image: url('/images/feature.jpg');
background-position: 25% 75%; /* 25% from left, 75% from top */
}
background-repeat
/* Background repeat examples */
.repeat-bg {
background-image: url('/images/tile.png');
background-repeat: repeat; /* Repeat both horizontally and vertically (default) */
}
.no-repeat-bg {
background-image: url('/images/single-image.jpg');
background-repeat: no-repeat; /* Don't repeat the image */
}
.repeat-x-bg {
background-image: url('/images/horizontal-pattern.png');
background-repeat: repeat-x; /* Repeat only horizontally */
}
.repeat-y-bg {
background-image: url('/images/vertical-pattern.png');
background-repeat: repeat-y; /* Repeat only vertically */
}
.space-bg {
background-image: url('/images/icon.png');
background-repeat: space; /* Repeat without clipping, adding space between */
}
.round-bg {
background-image: url('/images/icon.png');
background-repeat: round; /* Repeat and scale to fit whole number of images */
}
background-attachment
/* Background attachment examples */
.scroll-bg {
background-image: url('/images/texture.jpg');
background-attachment: scroll; /* Scroll with the element (default) */
}
.fixed-bg {
background-image: url('/images/parallax.jpg');
background-attachment: fixed; /* Fixed within viewport */
}
.local-bg {
background-image: url('/images/pattern.jpg');
background-attachment: local; /* Scroll with element's content */
}
Background Shorthand
The background shorthand property combines multiple background properties:
/* Background shorthand syntax */
.element {
/* color | image | position | size | repeat | attachment */
background: #f5f5f5 url('/images/pattern.png') center / cover no-repeat fixed;
}
Multiple Backgrounds
CSS allows multiple background layers, with the first one on top:
/* Multiple backgrounds example */
.layered-bg {
background:
linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), /* Dark overlay */
url('/images/hero.jpg') center / cover no-repeat; /* Base image */
}
Gradient Backgrounds
CSS gradients create smooth transitions between colors:
Linear Gradients
/* Linear gradient examples */
.vertical-gradient {
background: linear-gradient(#0066cc, #004c99); /* Top to bottom */
}
.horizontal-gradient {
background: linear-gradient(to right, #0066cc, #004c99); /* Left to right */
}
.diagonal-gradient {
background: linear-gradient(45deg, #0066cc, #004c99); /* 45 degree angle */
}
.multi-stop-gradient {
background: linear-gradient(to bottom, #f5f5f5, #e0e0e0, #d0d0d0);
}
.transparent-gradient {
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0));
}
Radial Gradients
/* Radial gradient examples */
.simple-radial {
background: radial-gradient(#0066cc, #004c99); /* Circular gradient */
}
.elliptical-radial {
background: radial-gradient(ellipse, #0066cc, #004c99); /* Elliptical gradient */
}
.positioned-radial {
background: radial-gradient(circle at top right, #0066cc, #004c99);
}
.multi-stop-radial {
background: radial-gradient(circle, #ffffff, #f0f0f0, #d0d0d0);
}
Repeating Gradients
/* Repeating gradient examples */
.repeating-linear {
background: repeating-linear-gradient(
45deg,
#f5f5f5,
#f5f5f5 10px,
#e0e0e0 10px,
#e0e0e0 20px
);
}
.repeating-radial {
background: repeating-radial-gradient(
circle,
#f5f5f5,
#f5f5f5 10px,
#e0e0e0 10px,
#e0e0e0 20px
);
}
Practical Background Techniques
Hero Sections
/* Hero section with overlay */
.hero {
background:
linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.6)),
url('/images/hero.jpg') center / cover no-repeat;
height: 80vh;
display: flex;
align-items: center;
justify-content: center;
color: white;
}
/* Parallax effect */
.parallax-section {
background:
url('/images/parallax-bg.jpg') center / cover no-repeat fixed;
min-height: 400px;
}
Patterns and Textures
/* Subtle background patterns */
.subtle-pattern {
background:
url('/images/subtle-pattern.png') repeat;
background-color: #f9f9f9;
}
/* CSS pattern without images */
.stripe-pattern {
background: repeating-linear-gradient(
45deg,
#f8f9fa,
#f8f9fa 10px,
#e9ecef 10px,
#e9ecef 20px
);
}
Modern UI Effects
/* Frosted glass effect */
.frosted-glass {
background: rgba(255, 255, 255, 0.3);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
/* Gradient button */
.gradient-button {
background: linear-gradient(45deg, #ff6b6b, #ff8e53);
border: none;
color: white;
padding: 10px 20px;
border-radius: 4px;
transition: all 0.3s ease;
}
.gradient-button:hover {
background: linear-gradient(45deg, #ff8e53, #ff6b6b);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
Working with Borders
Borders define the edges of elements, creating visual boundaries and enhancing the structure of your layout.
Border Properties
A border has three key characteristics: width, style, and color.
Border Width
/* Border width examples */
.thin-border {
border-width: 1px;
}
.medium-border {
border-width: 3px;
}
.thick-border {
border-width: 8px;
}
.varying-border {
/* top | right | bottom | left */
border-width: 1px 2px 3px 4px;
}
.horizontal-vertical-border {
/* vertical | horizontal */
border-width: 1px 2px;
}
Border Style
/* Border style examples */
.solid-border {
border-style: solid; /* Most common style */
}
.dashed-border {
border-style: dashed;
}
.dotted-border {
border-style: dotted;
}
.double-border {
border-style: double; /* Requires a width of at least 3px */
}
.groove-border {
border-style: groove; /* 3D effect - appears carved in */
}
.ridge-border {
border-style: ridge; /* 3D effect - appears coming out */
}
.inset-border {
border-style: inset; /* 3D effect - entire element appears inset */
}
.outset-border {
border-style: outset; /* 3D effect - entire element appears raised */
}
.mixed-border {
/* top | right | bottom | left */
border-style: solid dashed dotted double;
}
Border Color
/* Border color examples */
.basic-border {
border-width: 1px;
border-style: solid;
border-color: #ccc; /* Light gray */
}
.colored-border {
border-width: 2px;
border-style: solid;
border-color: #0066cc; /* Blue */
}
.varying-color-border {
border-width: 2px;
border-style: solid;
/* top | right | bottom | left */
border-color: red green blue yellow;
}
.transparent-border {
border-width: 5px;
border-style: solid;
border-color: rgba(0, 102, 204, 0.3); /* Semi-transparent blue */
}
Border Shorthand
The border shorthand property combines width, style, and color:
/* Border shorthand examples */
.simple-border {
border: 1px solid #ccc;
}
.highlight-border {
border: 2px dashed #ff6b6b;
}
.thick-border {
border: 5px double #333;
}
Individual Border Sides
You can apply borders to specific sides of an element:
/* Individual border sides */
.bottom-border-only {
border-bottom: 1px solid #ccc;
}
.top-border-only {
border-top: 3px solid #0066cc;
}
.left-right-borders {
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
}
/* Individual border properties per side */
.complex-border {
border-top-width: 2px;
border-top-style: solid;
border-top-color: red;
border-right-width: 3px;
border-right-style: dashed;
border-right-color: green;
border-bottom-width: 4px;
border-bottom-style: dotted;
border-bottom-color: blue;
border-left-width: 5px;
border-left-style: double;
border-left-color: orange;
}
Border Radius
The border-radius property creates rounded corners:
/* Border radius examples */
.slightly-rounded {
border-radius: 4px;
}
.rounded {
border-radius: 8px;
}
.very-rounded {
border-radius: 16px;
}
.pill-shape {
border-radius: 999px; /* Large value creates pill shape */
}
.circle {
width: 100px;
height: 100px;
border-radius: 50%; /* 50% creates a perfect circle when width = height */
}
.varying-radius {
/* top-left | top-right | bottom-right | bottom-left */
border-radius: 4px 8px 12px 16px;
}
.elliptical-corners {
/* horizontal/vertical radius for each corner */
border-radius: 50% 20% / 10% 40%;
}
Border Images
The border-image property allows using images for borders:
/* Border image example */
.image-border {
border: 15px solid transparent;
border-image: url('/images/border-pattern.png') 30 round;
}
/* Border image with slice, width, and outset */
.complex-image-border {
border: 20px solid transparent;
border-image-source: url('/images/border-pattern.png');
border-image-slice: 40;
border-image-width: 20px;
border-image-outset: 10px;
border-image-repeat: round;
}
Note: Border images are powerful but complex, and require specially prepared image files to work effectively.
Practical Border Applications
UI Component Borders
/* Card component */
.card {
background-color: white;
border: 1px solid rgba(0, 0, 0, 0.125);
border-radius: 8px;
padding: 20px;
}
/* Button styles */
.button {
background-color: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 4px;
padding: 8px 16px;
transition: all 0.2s ease;
}
.button:hover {
border-color: #c6c7c8;
}
.button-primary {
background-color: #0066cc;
border-color: #0066cc;
color: white;
}
.button-primary:hover {
background-color: #0055aa;
border-color: #004c99;
}
Form Element Borders
/* Form input styling */
.form-input {
border: 1px solid #ced4da;
border-radius: 4px;
padding: 8px 12px;
width: 100%;
transition: border-color 0.15s ease-in-out;
}
.form-input:focus {
border-color: #80bdff;
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
.form-input.is-invalid {
border-color: #dc3545;
}
.form-input.is-valid {
border-color: #28a745;
}
Decorative and Emphasis Borders
/* Decorative borders */
.decorative-heading {
position: relative;
padding-bottom: 10px;
}
.decorative-heading::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 50px;
border-bottom: 3px solid #0066cc;
}
/* Callout box */
.callout {
border-left: 4px solid #0066cc;
background-color: #f0f7ff;
padding: 15px;
margin: 20px 0;
}
/* Different callout types */
.callout-warning {
border-left-color: #ffc107;
background-color: #fff9e6;
}
.callout-danger {
border-left-color: #dc3545;
background-color: #ffeaed;
}
Interactive Border Effects
/* Animated border on hover */
.hover-border-effect {
border: 2px solid transparent;
transition: border-color 0.3s ease;
}
.hover-border-effect:hover {
border-color: #0066cc;
}
/* Gradient border */
.gradient-border {
border: 4px solid;
border-image: linear-gradient(45deg, #ff6b6b, #ff8e53) 1;
}
/* Animated border thickness */
.border-thickness-animation {
position: relative;
}
.border-thickness-animation::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
border-bottom: 1px solid #0066cc;
transition: border-width 0.2s ease;
}
.border-thickness-animation:hover::after {
border-width: 3px;
}
Enhancing Elements with Shadows and Outlines
While not strictly borders, shadows and outlines complement borders to create depth and emphasis.
Box Shadow
The box-shadow property adds shadow effects around an element's frame:
/* Box shadow examples */
.basic-shadow {
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.medium-shadow {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.large-shadow {
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
}
/* x-offset | y-offset | blur-radius | spread-radius | color */
.complex-shadow {
box-shadow: 0 5px 15px 5px rgba(0, 0, 0, 0.1);
}
.inset-shadow {
box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.1);
}
.multiple-shadows {
box-shadow:
0 2px 5px rgba(0, 0, 0, 0.1),
0 10px 20px rgba(0, 0, 0, 0.05);
}
.colored-shadow {
box-shadow: 0 5px 15px rgba(0, 102, 204, 0.3);
}
Text Shadow
The text-shadow property adds shadows to text:
/* Text shadow examples */
.subtle-text-shadow {
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
}
.glow-effect {
text-shadow: 0 0 8px rgba(0, 102, 204, 0.5);
}
.hard-shadow {
text-shadow: 3px 3px 0 #000;
}
.multiple-text-shadows {
text-shadow:
1px 1px 0 #000,
-1px -1px 0 #000;
}
Outline
The outline property creates a line around elements, outside of borders:
/* Outline examples */
.basic-outline {
outline: 1px solid #0066cc;
}
.thick-outline {
outline: 3px dashed #ff6b6b;
}
.outline-offset {
outline: 2px solid #0066cc;
outline-offset: 3px; /* Space between border and outline */
}
Key difference: Unlike borders, outlines don't affect layout (they don't take up space), and they don't support individual sides or border-radius.
Focus Styles
Outlines are particularly important for form elements and interactive components:
/* Focus style examples */
/* Default browser focus style (not recommended to remove without replacement) */
:focus {
outline: auto;
}
/* Custom focus style */
.custom-focus:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.5);
}
/* Accessible button focus */
.button:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.5);
}
/* Focus style for dark backgrounds */
.dark-theme .button:focus {
box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.5);
}
Accessibility note: Never remove outlines without providing an alternative focus indicator. Focus styles are essential for keyboard navigation.
Putting It All Together: Real-World Examples
Let's combine colors, backgrounds, and borders to create practical UI components.
Card Component
/* Card component with shadows and hover effects */
.card {
background-color: white;
border-radius: 8px;
border: 1px solid rgba(0, 0, 0, 0.08);
padding: 20px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
.card-header {
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
padding-bottom: 15px;
margin-bottom: 15px;
}
.card-title {
color: #333;
margin-top: 0;
margin-bottom: 5px;
}
.card-subtitle {
color: #666;
margin-top: 0;
margin-bottom: 0;
}
.card-image {
margin: -20px -20px 20px -20px;
border-radius: 8px 8px 0 0;
overflow: hidden;
}
.card-image img {
width: 100%;
display: block;
}
.card-footer {
border-top: 1px solid rgba(0, 0, 0, 0.08);
margin-top: 15px;
padding-top: 15px;
display: flex;
justify-content: flex-end;
}
Button System
/* Comprehensive button system */
.btn {
display: inline-block;
font-weight: 500;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
padding: 8px 16px;
font-size: 14px;
line-height: 1.5;
border-radius: 4px;
transition: all 0.2s ease-in-out;
border: 1px solid transparent;
}
.btn:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.25);
}
/* Primary button */
.btn-primary {
color: white;
background-color: #0066cc;
border-color: #0066cc;
}
.btn-primary:hover {
background-color: #0055aa;
border-color: #004c99;
}
/* Secondary button */
.btn-secondary {
color: #333;
background-color: #f8f9fa;
border-color: #dee2e6;
}
.btn-secondary:hover {
background-color: #e2e6ea;
border-color: #c6c7c8;
}
/* Success button */
.btn-success {
color: white;
background-color: #28a745;
border-color: #28a745;
}
.btn-success:hover {
background-color: #218838;
border-color: #1e7e34;
}
/* Danger button */
.btn-danger {
color: white;
background-color: #dc3545;
border-color: #dc3545;
}
.btn-danger:hover {
background-color: #c82333;
border-color: #bd2130;
}
/* Outline variant */
.btn-outline-primary {
color: #0066cc;
background-color: transparent;
border-color: #0066cc;
}
.btn-outline-primary:hover {
color: white;
background-color: #0066cc;
border-color: #0066cc;
}
/* Button sizes */
.btn-sm {
padding: 4px 8px;
font-size: 12px;
}
.btn-lg {
padding: 12px 24px;
font-size: 16px;
}
/* Button states */
.btn:disabled, .btn.disabled {
opacity: 0.65;
cursor: not-allowed;
}
.btn-loading {
position: relative;
color: transparent !important;
}
.btn-loading::after {
content: '';
position: absolute;
width: 16px;
height: 16px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top-color: white;
left: calc(50% - 8px);
top: calc(50% - 8px);
animation: btn-spinner 0.8s linear infinite;
}
@keyframes btn-spinner {
to { transform: rotate(360deg); }
}
Alert Component
/* Alert component with variations */
.alert {
padding: 12px 16px;
border-radius: 4px;
margin-bottom: 20px;
border: 1px solid transparent;
}
.alert-heading {
margin-top: 0;
margin-bottom: 8px;
font-weight: 600;
}
.alert-text {
margin-top: 0;
margin-bottom: 0;
}
/* Info alert */
.alert-info {
color: #0c5460;
background-color: #d1ecf1;
border-color: #bee5eb;
}
/* Success alert */
.alert-success {
color: #155724;
background-color: #d4edda;
border-color: #c3e6cb;
}
/* Warning alert */
.alert-warning {
color: #856404;
background-color: #fff3cd;
border-color: #ffeeba;
}
/* Danger alert */
.alert-danger {
color: #721c24;
background-color: #f8d7da;
border-color: #f5c6cb;
}
/* Alert with icon */
.alert-with-icon {
position: relative;
padding-left: 48px;
}
.alert-icon {
position: absolute;
left: 16px;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
}
/* Alert with dismiss button */
.alert-dismissible {
padding-right: 40px;
}
.alert-dismiss-btn {
position: absolute;
top: 12px;
right: 16px;
padding: 0;
background: transparent;
border: 0;
font-size: 20px;
font-weight: 700;
line-height: 1;
color: inherit;
cursor: pointer;
opacity: 0.5;
}
.alert-dismiss-btn:hover {
opacity: 1;
}
Form Elements
/* Form elements with proper styling */
.form-control {
display: block;
width: 100%;
padding: 8px 12px;
font-size: 14px;
line-height: 1.5;
color: #495057;
background-color: white;
border: 1px solid #ced4da;
border-radius: 4px;
transition: all 0.15s ease-in-out;
}
.form-control:focus {
color: #495057;
background-color: white;
border-color: #80bdff;
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
.form-control::placeholder {
color: #6c757d;
opacity: 1;
}
/* Form validation states */
.form-control.is-valid {
border-color: #28a745;
padding-right: 32px;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 12px center;
background-size: 16px 12px;
}
.form-control.is-valid:focus {
border-color: #28a745;
box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);
}
.form-control.is-invalid {
border-color: #dc3545;
padding-right: 32px;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 12px center;
background-size: 16px 12px;
}
.form-control.is-invalid:focus {
border-color: #dc3545;
box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
}
/* Custom checkbox */
.form-check {
position: relative;
padding-left: 24px;
}
.form-check-input {
position: absolute;
margin-top: 4px;
margin-left: -24px;
}
.form-check-label {
margin-bottom: 0;
}
Accessibility and Performance Considerations
Color Accessibility
When working with colors, always consider accessibility:
- Contrast ratio: Ensure text has sufficient contrast against its background
- Color independence: Don't rely solely on color to convey information
- Focus visibility: Make sure focus indicators are clearly visible
/* Accessible color contrast example */
/* Good contrast */
.accessible-text {
color: #333; /* Dark gray text */
background-color: #f5f5f5; /* Light gray background */
}
/* Poor contrast - avoid */
.inaccessible-text {
color: #999; /* Light gray text */
background-color: #f5f5f5; /* Light gray background */
}
/* Combining color with other visual cues */
.error-message {
color: #cc0000; /* Red for error state */
background-color: #fff0f0; /* Light red background */
border-left: 4px solid #cc0000; /* Red left border as additional cue */
padding-left: 10px;
}
Performance Optimizations
Some visual effects can impact performance if not implemented carefully:
- Box shadows: Complex or multiple shadows can be computationally expensive
- Background images: Large or unoptimized images can slow down page loads
- Gradients: Complex gradients with many color stops may impact rendering
- Animations: Transitions of certain properties (like box-shadow) can be less smooth
/* Performance-conscious practices */
/* Use transform and opacity for animations (hardware-accelerated) */
.optimized-hover {
transition: transform 0.3s ease, opacity 0.3s ease;
}
.optimized-hover:hover {
transform: translateY(-5px);
opacity: 0.9;
}
/* Pre-loading important background images */
.preload-bg {
position: absolute;
left: -9999px;
width: 1px;
height: 1px;
background-image: url('/images/important-bg.jpg');
}
/* Using CSS properties that avoid repaints */
.efficient-animation {
transition: transform 0.3s ease; /* Good - uses compositing */
}
.inefficient-animation {
transition: box-shadow 0.3s ease; /* Less efficient - causes repaint */
}
Advanced Design Techniques
As you become more comfortable with colors, backgrounds, and borders, explore these advanced techniques:
CSS Custom Properties for Theming
/* CSS variables for theming */
:root {
/* Light theme (default) */
--color-bg: #ffffff;
--color-text: #333333;
--color-primary: #0066cc;
--color-secondary: #6c757d;
--color-border: #dee2e6;
--shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
/* Dark theme */
.dark-theme {
--color-bg: #222222;
--color-text: #f0f0f0;
--color-primary: #4d94ff;
--color-secondary: #adb5bd;
--color-border: #444444;
--shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
}
/* Using theme variables */
body {
background-color: var(--color-bg);
color: var(--color-text);
}
.card {
border: 1px solid var(--color-border);
box-shadow: var(--shadow);
}
Multiple Border Effects
/* Creating multiple border effects */
.double-border-effect {
border: 2px solid #333;
box-shadow: 0 0 0 5px #fff, 0 0 0 7px #333;
}
/* Dashed inner border */
.inner-border {
border: 2px solid #333;
box-shadow: inset 0 0 0 3px #fff, inset 0 0 0 5px #333;
}
/* Border with gradient */
.gradient-border {
position: relative;
background: white;
padding: 20px;
z-index: 1;
}
.gradient-border::before {
content: "";
position: absolute;
top: -3px;
left: -3px;
right: -3px;
bottom: -3px;
background: linear-gradient(45deg, #ff6b6b, #ff8e53, #70c1ff, #5e60ce);
z-index: -1;
border-radius: 10px;
}
Complex Background Patterns
/* Complex CSS patterns without images */
.checkerboard {
background-color: #f8f8f8;
background-image:
linear-gradient(45deg, #ddd 25%, transparent 25%),
linear-gradient(-45deg, #ddd 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, #ddd 75%),
linear-gradient(-45deg, transparent 75%, #ddd 75%);
background-size: 20px 20px;
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
}
.stripes {
background: repeating-linear-gradient(
45deg,
#f8f9fa,
#f8f9fa 10px,
#e9ecef 10px,
#e9ecef 20px
);
}
.polka-dots {
background-color: #f8f8f8;
background-image: radial-gradient(#ddd 3px, transparent 4px);
background-size: 20px 20px;
}
Background Blend Modes
/* Background blend modes */
.multiply-blend {
background:
url('/images/texture.jpg'),
linear-gradient(to right, #ff6b6b, #5e60ce);
background-blend-mode: multiply;
}
.overlay-blend {
background:
url('/images/pattern.jpg'),
radial-gradient(circle, #fff, #333);
background-blend-mode: overlay;
}
.color-burn-blend {
background:
url('/images/photo.jpg'),
linear-gradient(to bottom, #ff6b6b, transparent);
background-blend-mode: color-burn;
}
Hands-On Exercise: Design System Components
Let's apply what we've learned by creating the foundations of a design system using colors, backgrounds, and borders.
Exercise Overview
In this exercise, we'll build a simple design system with consistent visual elements.
HTML Structure
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Design System Components</title>
<link rel="stylesheet" href="/styles/visual_elements.css">
</head>
<body>
<div class="container">
<header class="header">
<h1>Design System Components</h1>
<p class="subtitle">A demonstration of colors, backgrounds, and borders</p>
</header>
<section class="section">
<h2>Color Palette</h2>
<div class="color-grid">
<div class="color-item primary">
<div class="color-swatch"></div>
<div class="color-info">
<h3>Primary</h3>
<code>var(--color-primary)</code>
</div>
</div>
<div class="color-item secondary">
<div class="color-swatch"></div>
<div class="color-info">
<h3>Secondary</h3>
<code>var(--color-secondary)</code>
</div>
</div>
<div class="color-item success">
<div class="color-swatch"></div>
<div class="color-info">
<h3>Success</h3>
<code>var(--color-success)</code>
</div>
</div>
<div class="color-item danger">
<div class="color-swatch"></div>
<div class="color-info">
<h3>Danger</h3>
<code>var(--color-danger)</code>
</div>
</div>
<div class="color-item warning">
<div class="color-swatch"></div>
<div class="color-info">
<h3>Warning</h3>
<code>var(--color-warning)</code>
</div>
</div>
<div class="color-item info">
<div class="color-swatch"></div>
<div class="color-info">
<h3>Info</h3>
<code>var(--color-info)</code>
</div>
</div>
</div>
</section>
<section class="section">
<h2>Buttons</h2>
<div class="button-grid">
<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-success">Success</button>
<button class="btn btn-danger">Danger</button>
<button class="btn btn-warning">Warning</button>
<button class="btn btn-info">Info</button>
<button class="btn btn-outline-primary">Outline</button>
</div>
</section>
<section class="section">
<h2>Cards</h2>
<div class="card-grid">
<div class="card">
<div class="card-header">
<h3 class="card-title">Basic Card</h3>
</div>
<div class="card-body">
<p>This is a basic card with a border and subtle shadow.</p>
</div>
<div class="card-footer">
<button class="btn btn-sm btn-primary">Action</button>
</div>
</div>
<div class="card card-hover">
<div class="card-header">
<h3 class="card-title">Hover Effect</h3>
</div>
<div class="card-body">
<p>This card has a hover effect with shadow and transform.</p>
</div>
<div class="card-footer">
<button class="btn btn-sm btn-primary">Action</button>
</div>
</div>
<div class="card card-border">
<div class="card-header">
<h3 class="card-title">Border Accent</h3>
</div>
<div class="card-body">
<p>This card has a colored border accent on the left side.</p>
</div>
<div class="card-footer">
<button class="btn btn-sm btn-primary">Action</button>
</div>
</div>
</div>
</section>
<section class="section">
<h2>Alerts</h2>
<div class="alert alert-primary">
<h3 class="alert-heading">Primary Alert</h3>
<p class="alert-text">This is a primary alert with a colored background and border.</p>
</div>
<div class="alert alert-success">
<h3 class="alert-heading">Success Alert</h3>
<p class="alert-text">This is a success alert indicating a completed action.</p>
</div>
<div class="alert alert-warning">
<h3 class="alert-heading">Warning Alert</h3>
<p class="alert-text">This is a warning alert indicating a potential issue.</p>
</div>
<div class="alert alert-danger">
<h3 class="alert-heading">Danger Alert</h3>
<p class="alert-text">This is a danger alert indicating a critical error.</p>
</div>
</section>
<section class="section">
<h2>Form Elements</h2>
<form class="form">
<div class="form-group">
<label for="text-input">Text Input</label>
<input type="text" id="text-input" class="form-control" placeholder="Enter text">
</div>
<div class="form-group">
<label for="text-input-focus">Focused Input</label>
<input type="text" id="text-input-focus" class="form-control focus-demo" placeholder="Focused state">
</div>
<div class="form-group">
<label for="text-input-valid">Valid Input</label>
<input type="text" id="text-input-valid" class="form-control is-valid" value="Correctly filled">
</div>
<div class="form-group">
<label for="text-input-invalid">Invalid Input</label>
<input type="text" id="text-input-invalid" class="form-control is-invalid" value="Incorrect value">
</div>
</form>
</section>
</div>
</body>
</html>
CSS Implementation
/* Design System CSS */
/* Base Styles and Variables */
:root {
/* Color Palette */
--color-primary: #0066cc;
--color-primary-dark: #0055aa;
--color-primary-light: #4d94ff;
--color-secondary: #6c757d;
--color-secondary-dark: #5a6268;
--color-secondary-light: #adb5bd;
--color-success: #28a745;
--color-success-dark: #218838;
--color-success-light: #86e29b;
--color-danger: #dc3545;
--color-danger-dark: #c82333;
--color-danger-light: #f5c2c7;
--color-warning: #ffc107;
--color-warning-dark: #e0a800;
--color-warning-light: #ffe69c;
--color-info: #17a2b8;
--color-info-dark: #138496;
--color-info-light: #9eeaf9;
/* Neutrals */
--color-dark: #343a40;
--color-light: #f8f9fa;
--color-gray: #6c757d;
--color-gray-dark: #343a40;
--color-gray-light: #e9ecef;
/* Background and Text */
--color-bg: #ffffff;
--color-text: #333333;
--color-text-light: #555555;
--color-text-muted: #6c757d;
/* Borders */
--color-border: #dee2e6;
--border-radius-sm: 4px;
--border-radius: 8px;
--border-radius-lg: 12px;
--border-width: 1px;
/* Shadows */
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1);
--shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 5px 15px rgba(0, 0, 0, 0.1);
/* Transitions */
--transition-speed: 0.3s;
--transition-timing: ease;
}
/* Base styles */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: Arial, sans-serif;
line-height: 1.6;
color: var(--color-text);
background-color: var(--color-light);
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
.header {
margin-bottom: 3rem;
padding-bottom: 1rem;
border-bottom: 1px solid var(--color-border);
}
h1 {
color: var(--color-dark);
margin-bottom: 0.5rem;
}
.subtitle {
color: var(--color-text-muted);
font-size: 1.2rem;
}
.section {
margin-bottom: 3rem;
}
h2 {
color: var(--color-dark);
margin-bottom: 1.5rem;
position: relative;
padding-bottom: 0.5rem;
}
h2::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 50px;
height: 3px;
background-color: var(--color-primary);
}
/* Color palette section */
.color-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1.5rem;
}
.color-item {
border-radius: var(--border-radius);
overflow: hidden;
box-shadow: var(--shadow);
background-color: white;
}
.color-swatch {
height: 100px;
}
.color-info {
padding: 1rem;
}
.color-info h3 {
margin-bottom: 0.5rem;
font-size: 1rem;
}
.color-info code {
font-size: 0.875rem;
color: var(--color-text-muted);
}
.primary .color-swatch {
background-color: var(--color-primary);
}
.secondary .color-swatch {
background-color: var(--color-secondary);
}
.success .color-swatch {
background-color: var(--color-success);
}
.danger .color-swatch {
background-color: var(--color-danger);
}
.warning .color-swatch {
background-color: var(--color-warning);
}
.info .color-swatch {
background-color: var(--color-info);
}
/* Buttons */
.button-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: 1rem;
}
.btn {
display: inline-block;
font-weight: 500;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
padding: 0.5rem 1rem;
font-size: 1rem;
line-height: 1.5;
border-radius: var(--border-radius-sm);
transition: all var(--transition-speed) var(--transition-timing);
border: var(--border-width) solid transparent;
}
.btn-sm {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
}
.btn:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.25);
}
.btn-primary {
color: white;
background-color: var(--color-primary);
border-color: var(--color-primary);
}
.btn-primary:hover {
background-color: var(--color-primary-dark);
border-color: var(--color-primary-dark);
}
.btn-secondary {
color: white;
background-color: var(--color-secondary);
border-color: var(--color-secondary);
}
.btn-secondary:hover {
background-color: var(--color-secondary-dark);
border-color: var(--color-secondary-dark);
}
.btn-success {
color: white;
background-color: var(--color-success);
border-color: var(--color-success);
}
.btn-success:hover {
background-color: var(--color-success-dark);
border-color: var(--color-success-dark);
}
.btn-danger {
color: white;
background-color: var(--color-danger);
border-color: var(--color-danger);
}
.btn-danger:hover {
background-color: var(--color-danger-dark);
border-color: var(--color-danger-dark);
}
.btn-warning {
color: var(--color-dark);
background-color: var(--color-warning);
border-color: var(--color-warning);
}
.btn-warning:hover {
background-color: var(--color-warning-dark);
border-color: var(--color-warning-dark);
}
.btn-info {
color: white;
background-color: var(--color-info);
border-color: var(--color-info);
}
.btn-info:hover {
background-color: var(--color-info-dark);
border-color: var(--color-info-dark);
}
.btn-outline-primary {
color: var(--color-primary);
background-color: transparent;
border-color: var(--color-primary);
}
.btn-outline-primary:hover {
color: white;
background-color: var(--color-primary);
}
/* Cards */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
}
.card {
background-color: white;
border-radius: var(--border-radius);
border: var(--border-width) solid var(--color-border);
overflow: hidden;
box-shadow: var(--shadow);
}
.card-header {
padding: 1rem;
border-bottom: var(--border-width) solid var(--color-border);
background-color: var(--color-light);
}
.card-title {
margin: 0;
font-size: 1.25rem;
}
.card-body {
padding: 1rem;
}
.card-footer {
padding: 1rem;
border-top: var(--border-width) solid var(--color-border);
background-color: var(--color-light);
}
.card-hover {
transition: transform var(--transition-speed) var(--transition-timing),
box-shadow var(--transition-speed) var(--transition-timing);
}
.card-hover:hover {
transform: translateY(-5px);
box-shadow: var(--shadow-lg);
}
.card-border {
border-left: 4px solid var(--color-primary);
}
/* Alerts */
.alert {
padding: 1rem;
border-radius: var(--border-radius);
margin-bottom: 1rem;
border: var(--border-width) solid transparent;
}
.alert-heading {
margin-top: 0;
margin-bottom: 0.5rem;
font-size: 1.1rem;
}
.alert-text {
margin: 0;
}
.alert-primary {
color: #004085;
background-color: #cce5ff;
border-color: #b8daff;
}
.alert-success {
color: #155724;
background-color: #d4edda;
border-color: #c3e6cb;
}
.alert-warning {
color: #856404;
background-color: #fff3cd;
border-color: #ffeeba;
}
.alert-danger {
color: #721c24;
background-color: #f8d7da;
border-color: #f5c6cb;
}
/* Form elements */
.form {
max-width: 600px;
}
.form-group {
margin-bottom: 1rem;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
font-weight: 500;
}
.form-control {
display: block;
width: 100%;
padding: 0.5rem 0.75rem;
font-size: 1rem;
line-height: 1.5;
color: var(--color-text);
background-color: white;
border: var(--border-width) solid var(--color-border);
border-radius: var(--border-radius-sm);
transition: all 0.15s ease-in-out;
}
.form-control:focus {
border-color: var(--color-primary-light);
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
.focus-demo {
border-color: var(--color-primary-light);
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
.form-control.is-valid {
border-color: var(--color-success);
padding-right: 2rem;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 0.75rem center;
background-size: 1rem;
}
.form-control.is-valid:focus {
border-color: var(--color-success);
box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);
}
.form-control.is-invalid {
border-color: var(--color-danger);
padding-right: 2rem;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 0.75rem center;
background-size: 1rem;
}
.form-control.is-invalid:focus {
border-color: var(--color-danger);
box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
}
Exercise Analysis
This exercise demonstrates several key concepts:
- Color system: Using CSS variables to create a consistent and maintainable color palette
- Background usage: Applying background colors appropriately to create visual hierarchy
- Border techniques: Various border styles for different UI components
- Design consistency: Reusing colors, spacing, and border radiuses across components
- Interactive states: Implementing hover and focus states with visual feedback
- Visual feedback: Using colors and borders to communicate validity and state
The exercise creates a mini design system with consistent visual elements that could be extended to build a complete website or application.
Further Resources and Next Steps
Tools and References
- Coolors - Color scheme generator
- Adobe Color - Color wheel and harmony tools
- WebAIM Contrast Checker - Accessibility testing for color contrast
- CSS Gradient - Gradient generator
- ColorZilla - Color picker browser extension
- Hero Patterns - SVG background patterns
- uiGradients - Beautiful color gradients
Further Learning
- A Simple Web Developer's Guide To Color
- WebGradients - Collection of 180+ linear gradients
- The 7-Step Guide to Understanding Color Theory
- MDN: Using CSS gradients
- MDN: CSS Backgrounds and Borders
Advanced Topics to Explore
- SVG Backgrounds: Creating custom, scalable vector backgrounds
- CSS Filters: Adding visual effects to elements
- CSS Masks: Advanced masking techniques for creative backgrounds
- CSS Custom Properties: Building dynamic theming systems
- Color Theory: Deep dive into color psychology and accessibility
- Design Systems: Building comprehensive visual languages
Today's Assignment: Design System Implementation
Now it's your turn to apply what you've learned about colors, backgrounds, and borders.
Assignment Requirements:
- Create a new file called
styles/design_system.css - Create a corresponding HTML file called
design_system.html - Implement a personal design system with the following components:
- A color palette with at least 5 colors (primary, secondary, and 3 accent colors)
- A set of button styles (primary, secondary, outline, and disabled)
- Card components with different border and background treatments
- Alert/message components for different types of notifications
- Form elements with appropriate states (default, focus, valid, invalid)
- Use CSS custom properties (variables) for all colors and reusable values
- Implement hover and focus states for interactive elements
- Ensure sufficient color contrast for accessibility
- Add comments in your CSS explaining your color choices and design decisions
- Create a page that showcases all components in a visually organized way
Bonus challenges:
- Implement a dark mode toggle using CSS variables
- Create gradient buttons or backgrounds
- Add custom background patterns using CSS (no images)
- Create a theme switcher with 2-3 different color schemes
- Add subtle animations or transitions for interactive elements
Submit your completed assignment by pushing both your HTML and CSS files to your course repository.
Wrapping Up
Congratulations! You've now explored the powerful visual building blocks of CSS: colors, backgrounds, and borders. These properties are fundamental to creating attractive, usable interfaces that guide users through your applications.
Key takeaways from today's session:
- Colors convey meaning and emotion, and should be chosen with purpose
- CSS offers multiple color notation systems, each with different advantages
- Background properties allow for rich visual treatments beyond simple colors
- Borders define boundaries and create visual structure
- Combining these properties creates a cohesive design language
- CSS variables help maintain consistency across components
- Always consider accessibility when choosing colors and contrast
- Interactive states provide important visual feedback to users
As you continue your CSS journey, you'll build on these foundational techniques to create increasingly sophisticated designs. The concepts you've learned today will serve as building blocks for more advanced layout techniques like Flexbox and Grid, which we'll explore in future sessions.
In our next session, we'll dive into CSS positioning, which gives you precise control over element placement within your layouts.
Any questions before we wrap up?