Back to designs
GéométriqueMonochromeAnimationClassique
Preview

Op Art Design Reference

Optical illusion art: geometric patterns creating visual movement and depth via contrast and repetition.


Overview

Op Art -- short for Optical Art -- is a style of abstract visual art that exploits the mechanics of human perception to produce illusions of movement, vibration, warping, and depth from entirely flat, static surfaces. The movement crystallized in the early 1960s, with the term itself coined by a Time magazine critic in 1964, though its roots stretch back to the color-interaction experiments of Josef Albers in the 1930s and the geometric abstractions of Victor Vasarely beginning in 1938. Vasarely, widely regarded as the father of Op Art, demonstrated with works like Zebras that precise arrangements of curvilinear black and white stripes could produce a visceral sense of three-dimensional form from flat shapes alone. The movement achieved mainstream recognition with the landmark 1965 exhibition "The Responsive Eye" at the Museum of Modern Art in New York, which showcased Bridget Riley, Richard Anuszkiewicz, Julian Stanczak, and other practitioners whose mathematically rigorous compositions confounded and delighted audiences.

At its core, Op Art is built on a deeply scientific understanding of how the eye and brain process pattern, contrast, and color adjacency. Artists exploit phenomena like simultaneous contrast (where complementary colors placed side by side appear to vibrate), Mach bands (where the eye exaggerates luminance differences at edges), and pattern-induced motion illusions (where repetitive geometric fields trick the visual cortex into perceiving movement that does not exist). The discipline demands meticulous precision -- clean edges, mathematically calculated spacing, and exact color relationships. Unlike expressionistic movements, there is no room for gestural looseness; the optical effect depends on absolute geometric control.

Translating Op Art to web design means embracing its power to arrest attention, create kinetic energy without animation, and produce visual complexity from simple, repeatable elements. CSS is remarkably well-suited to Op Art's vocabulary: repeating gradients, precise border calculations, transforms, and custom properties can reproduce the concentric circles, moire patterns, and checkerboard distortions that define the style. On screen, Op Art aesthetics work powerfully for hero sections, loading states, background textures, and accent elements. The key challenge is balance -- the same intensity that captivates can also overwhelm or cause discomfort if applied without restraint. Effective Op Art web design uses optical patterns as punctuation rather than prose, pairing high-contrast illusion zones with generous whitespace and clean typographic hierarchies so that the eye has room to rest between moments of perceptual challenge.


Visual Characteristics

Core Design Traits

  • High-contrast pattern fields -- black-and-white or complementary-color geometric arrays that produce the perception of movement, vibration, or pulsation on a completely flat surface
  • Precise geometric repetition -- concentric circles, parallel lines, radiating stripes, and tessellated grids repeated at mathematically exact intervals to exploit the eye's pattern-recognition threshold
  • Moire interference effects -- overlapping grids or curved line sets whose slight offset generates shimmering secondary patterns perceived by the brain but absent from the actual artwork
  • Figure-ground ambiguity -- compositions where foreground and background swap depending on the viewer's focal point, creating unstable spatial relationships that keep the eye in constant motion
  • Chromatic vibration -- complementary colors of equal saturation and brightness placed directly adjacent, causing the boundary between them to appear to shimmer or pulse (red-green, blue-orange, purple-yellow)
  • Concentric and radial structures -- rings, spirals, and sunbursts that create a sense of depth, tunneling, or expansion from the center outward
  • Warped grid distortion -- regular grids with controlled deformations (bulges, pinches, waves) that make flat surfaces appear to swell into three-dimensional forms
  • Clean hard edges -- no blur, no feathering, no anti-aliasing in the artistic intent; every boundary is razor-sharp to maximize the contrast differential that drives the optical effect
  • Mathematical precision -- spacing, angle, and proportion are calculated rather than intuited; many Op Art works can be described by formulas
  • Monochrome foundation with strategic color -- the strongest effects often begin in pure black and white, with color introduced deliberately for specific chromatic phenomena rather than decorative warmth
  • Bilateral or rotational symmetry -- compositions frequently employ mirror symmetry or rotational repetition, reinforcing pattern regularity and perceptual rhythm
  • Scalelessness -- the same pattern reads effectively at macro and micro scales, making Op Art motifs naturally resolution-independent and well-suited to responsive design

Design Principles

  • Perception is the medium: the artwork exists in the viewer's nervous system, not just on the surface
  • Precision over expression: mathematical accuracy is the instrument; gestural freedom would destroy the effect
  • Contrast is energy: the greater the luminance or chromatic differential, the stronger the visual event
  • Repetition builds power: a single stripe is inert; a hundred stripes in precise rhythm vibrate with apparent motion
  • Restraint defines impact: Op Art effects are most powerful when concentrated in defined zones surrounded by visual rest
  • Simplicity of element, complexity of result: the individual units (lines, circles, squares) are elementary; their collective behavior is perceptually rich
  • Flatness is a canvas for implied depth: three-dimensional illusion is achieved purely through two-dimensional patterning, without gradients or shading
  • The eye is an active participant: the design is incomplete until it is viewed; it requires a human perceptual system to complete the experience

Color Palette

Op Art's palette is rooted in maximizing perceptual contrast. The movement's earliest and most iconic works are strictly black and white, exploiting the maximum possible luminance differential. When color entered the Op Art vocabulary -- pioneered by artists like Bridget Riley (from 1967), Richard Anuszkiewicz, and Julian Stanczak -- it was deployed according to the principles of simultaneous contrast and chromatic vibration: complementary hues of equal intensity placed in direct adjacency to produce the most aggressive retinal stimulation. The palette below includes the essential black-white foundation alongside carefully chosen complementary pairs and high-saturation primaries that produce authentic Op Art chromatic effects.

Swatch Hex Role / Usage
#000000 #000000 Pure black -- primary pattern element, maximum contrast anchor
#FFFFFF #FFFFFF Pure white -- counter-pattern element, backgrounds, rest zones
#1A1A1A #1A1A1A Near-black -- text, UI surfaces, softer dark alternative
#F0F0F0 #F0F0F0 Off-white -- secondary backgrounds, reduced glare
#808080 #808080 Neutral gray -- transitional tone, muted structural elements
#FF0000 #FF0000 Vibrant red -- chromatic vibration pair with cyan/green
#00FF00 #00FF00 Vibrant green -- complementary to red, maximum chromatic tension
#0000FF #0000FF Pure blue -- vibration pair with orange, deep contrast
#FF8C00 #FF8C00 Vivid orange -- complementary to blue, warm high-energy accent
#8B00FF #8B00FF Electric violet -- complementary to yellow, psychedelic edge
#FFD700 #FFD700 Bright yellow -- complementary to violet, high luminance
#00CED1 #00CED1 Cyan-teal -- complementary to red-orange, cool contrast
#FF1493 #FF1493 Hot pink -- Bridget Riley-inspired chromatic stripe accent
#39FF14 #39FF14 Neon green -- extreme vibration against black or magenta
#333333 #333333 Dark charcoal -- secondary text, less harsh than pure black

CSS Custom Properties

:root {
  /* Core black & white */
  --op-black: #000000;
  --op-white: #ffffff;
  --op-near-black: #1a1a1a;
  --op-off-white: #f0f0f0;
  --op-gray: #808080;
  --op-charcoal: #333333;

  /* Complementary pair: Red / Green */
  --op-red: #ff0000;
  --op-green: #00ff00;

  /* Complementary pair: Blue / Orange */
  --op-blue: #0000ff;
  --op-orange: #ff8c00;

  /* Complementary pair: Violet / Yellow */
  --op-violet: #8b00ff;
  --op-yellow: #ffd700;

  /* Accent colors */
  --op-cyan: #00ced1;
  --op-hot-pink: #ff1493;
  --op-neon-green: #39ff14;

  /* Semantic tokens */
  --op-bg-primary: #ffffff;
  --op-bg-dark: #000000;
  --op-bg-soft: #f0f0f0;
  --op-text-primary: #000000;
  --op-text-inverse: #ffffff;
  --op-text-secondary: #333333;

  /* Pattern tokens */
  --op-stripe-width: 4px;
  --op-pattern-speed: 20s;
}

Typography

Op Art typography serves as a counterweight to the visual intensity of optical pattern fields. Type must be authoritative, geometric, and supremely legible -- it anchors the viewer's focus amid perceptual turbulence. Geometric sans-serif faces echo the mathematical precision of Op Art patterns while maintaining the clean hard edges essential to the aesthetic. Heavy weights command attention in heading roles, while lighter weights provide comfortable reading in body contexts. Avoid decorative, script, or serif faces that would clash with the rigorous geometry; type should feel like it was engineered on the same grid as the patterns themselves.

Font Weight(s) Usage Link
Space Grotesk 400, 500, 700 Headings, display text Google Fonts
Inter 400, 500, 700 Body text, UI elements Google Fonts
Outfit 400, 600, 800 Headings, labels Google Fonts
Syne 400, 700, 800 Display, hero text Google Fonts
DM Sans 400, 500, 700 Body, secondary text Google Fonts
Jost 400, 600, 700 Geometric headings Google Fonts
Barlow 400, 600, 700 Navigation, compact labels Google Fonts
Archivo 400, 700, 900 Bold headlines, impact text Google Fonts

Font Pairing Suggestions

Heading Body Vibe
Space Grotesk (700) Inter (400) Precise, engineered, modern
Syne (800) DM Sans (400) Bold art-world energy with clean readability
Outfit (800) Inter (400) Rounded geometry, friendly precision
Archivo (900) DM Sans (400) Maximum impact, high-contrast authority
Jost (700) Barlow (400) Bauhaus-descended geometric purity

CSS Example

/* Import fonts */
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Inter:wght@400;500;700&display=swap');

/* Headings */
h1, h2, h3, h4, h5, h6 {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  color: var(--op-text-primary);
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

/* Display / Hero text */
.op-display {
  font-family: 'Space Grotesk', sans-serif;
  font-size: clamp(3rem, 8vw, 7rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 0.95;
  text-transform: uppercase;
}

/* Body text */
body {
  font-family: 'Inter', sans-serif;
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.7;
  color: var(--op-text-secondary);
}

/* Labels and captions */
.op-label {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 500;
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.op-caption {
  font-family: 'Inter', sans-serif;
  font-weight: 400;
  font-size: 0.85rem;
  color: var(--op-gray);
  line-height: 1.5;
}

Layout Principles

  • Pattern zones vs. rest zones -- divide the layout into high-intensity pattern regions and generous whitespace breathing areas; never cover the entire viewport in optical patterns
  • Centered compositions -- Op Art's reliance on symmetry and radial structures favors centered layout axes for hero sections and feature blocks
  • Max-width containment -- constrain content to 1000-1200px to maintain pattern legibility and prevent optical effects from becoming disorienting at extreme widths
  • Generous vertical spacing -- sections need more padding than typical designs (80-120px) because the eye needs recovery space between intense pattern encounters
  • Grid-based pattern alignment -- pattern elements should snap to the same underlying grid as content, creating visual coherence between decoration and information
  • High-contrast section alternation -- alternate between black-background and white-background sections to create a macro-level rhythm that mirrors the micro-level stripe alternation of the patterns
  • Responsive pattern scaling -- use viewport units or clamp() for pattern dimensions so optical effects maintain their proportion and intensity across screen sizes
  • Minimal element count -- fewer, bolder elements; Op Art's visual complexity comes from the patterns, not from a large number of distinct UI components
  • Full-bleed pattern backgrounds -- key sections (hero, dividers, feature highlights) can use edge-to-edge pattern backgrounds while content floats in contained overlays
  • Typographic hierarchy through scale -- with patterns providing visual interest, type can rely on dramatic size contrast (very large headings, moderate body text) rather than color variation for hierarchy
  • Sticky or fixed navigation -- a solid-color nav bar provides a stable anchor at the top of the page, offering the eye a safe harbor amid the optical intensity below

CSS / Design Techniques

Op Art Card Component

A card component that uses a subtle optical pattern border and clean interior, creating depth through contrast between the patterned frame and the solid content area.

.op-card {
  background: var(--op-white);
  border: 3px solid var(--op-black);
  padding: 0;
  position: relative;
  overflow: hidden;
  transition: transform 0.3s ease;
}

.op-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 6px;
  background: repeating-linear-gradient(
    90deg,
    var(--op-black) 0px,
    var(--op-black) 3px,
    var(--op-white) 3px,
    var(--op-white) 6px
  );
}

.op-card__body {
  padding: 32px;
}

.op-card__title {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  font-size: 1.25rem;
  text-transform: uppercase;
  margin-bottom: 0.75rem;
}

.op-card__text {
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--op-text-secondary);
}

.op-card:hover {
  transform: scale(1.02);
}

.op-card:hover::before {
  background: repeating-linear-gradient(
    90deg,
    var(--op-red) 0px,
    var(--op-red) 3px,
    var(--op-white) 3px,
    var(--op-white) 6px
  );
}

.op-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 32px;
}

Op Art Button

Buttons with striped patterns that animate on hover, creating the impression that the button surface is vibrating -- a micro-scale Op Art effect contained within an interactive element.

.op-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--op-black);
  color: var(--op-white);
  border: 3px solid var(--op-black);
  border-radius: 0;
  padding: 14px 40px;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  font-size: 0.9rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  text-decoration: none;
  position: relative;
  overflow: hidden;
  transition: color 0.3s ease;
}

.op-button::before {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    45deg,
    transparent 0px,
    transparent 2px,
    rgba(255, 255, 255, 0.1) 2px,
    rgba(255, 255, 255, 0.1) 4px
  );
  opacity: 0;
  transition: opacity 0.3s ease;
}

.op-button:hover::before {
  opacity: 1;
}

.op-button:hover {
  background: var(--op-white);
  color: var(--op-black);
}

/* Inverted variant for dark backgrounds */
.op-button--inverse {
  background: var(--op-white);
  color: var(--op-black);
  border-color: var(--op-white);
}

.op-button--inverse:hover {
  background: var(--op-black);
  color: var(--op-white);
}

Op Art Navigation Bar

A clean, high-contrast navigation bar with an animated striped underline effect that provides visual interest without competing with the page's optical patterns.

.op-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px 40px;
  background: var(--op-white);
  border-bottom: 3px solid var(--op-black);
  position: sticky;
  top: 0;
  z-index: 100;
}

.op-nav__logo {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  font-size: 1.4rem;
  color: var(--op-black);
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.op-nav__logo-icon {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: repeating-radial-gradient(
    circle,
    var(--op-black) 0px,
    var(--op-black) 3px,
    var(--op-white) 3px,
    var(--op-white) 6px
  );
  border: 2px solid var(--op-black);
}

.op-nav__links {
  display: flex;
  gap: 32px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.op-nav__links a {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 500;
  font-size: 0.85rem;
  color: var(--op-black);
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  position: relative;
  transition: color 0.2s ease;
}

.op-nav__links a::after {
  content: '';
  position: absolute;
  bottom: -4px;
  left: 0;
  width: 100%;
  height: 3px;
  background: repeating-linear-gradient(
    90deg,
    var(--op-black) 0px,
    var(--op-black) 2px,
    transparent 2px,
    transparent 4px
  );
  transform: scaleX(0);
  transition: transform 0.3s ease;
}

.op-nav__links a:hover::after {
  transform: scaleX(1);
}

Op Art Hero Section

A dramatic hero with a full-bleed optical pattern background and centered content overlay, creating the signature Op Art sensation that the page surface is alive with movement.

.op-hero {
  position: relative;
  min-height: 90vh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--op-black);
}

.op-hero__pattern {
  position: absolute;
  inset: 0;
  background:
    repeating-conic-gradient(
      var(--op-black) 0deg 5deg,
      var(--op-white) 5deg 10deg
    );
  background-size: 100% 100%;
  background-position: center;
  opacity: 0.15;
}

.op-hero__content {
  position: relative;
  z-index: 2;
  text-align: center;
  max-width: 800px;
  padding: 60px 40px;
  background: rgba(0, 0, 0, 0.85);
}

.op-hero__content h1 {
  font-size: clamp(3rem, 8vw, 6rem);
  color: var(--op-white);
  font-weight: 700;
  line-height: 0.95;
  margin-bottom: 1.5rem;
  text-transform: uppercase;
  letter-spacing: -0.02em;
}

.op-hero__content p {
  font-size: 1.15rem;
  color: var(--op-off-white);
  max-width: 520px;
  margin: 0 auto 2rem;
  line-height: 1.7;
}

@media (max-width: 768px) {
  .op-hero {
    min-height: 70vh;
  }

  .op-hero__content {
    padding: 40px 24px;
  }
}

Concentric Circle Illusion

A pure CSS concentric ring pattern that creates the classic Op Art tunneling effect -- a circle-within-circle structure that appears to recede infinitely into depth.

.op-concentric {
  width: 400px;
  height: 400px;
  border-radius: 50%;
  background: repeating-radial-gradient(
    circle at center,
    var(--op-black) 0px,
    var(--op-black) 8px,
    var(--op-white) 8px,
    var(--op-white) 16px
  );
  margin: 0 auto;
  position: relative;
}

/* Animated variant: slowly rotates for enhanced depth illusion */
.op-concentric--animated {
  animation: op-pulse 4s ease-in-out infinite alternate;
}

@keyframes op-pulse {
  0% {
    transform: scale(1);
    background-size: 100% 100%;
  }
  100% {
    transform: scale(1.05);
    background-size: 110% 110%;
  }
}

/* Eccentric offset variant: off-center rings create a warp */
.op-concentric--warped {
  background: repeating-radial-gradient(
    circle at 40% 40%,
    var(--op-black) 0px,
    var(--op-black) 6px,
    var(--op-white) 6px,
    var(--op-white) 12px
  );
}

Moire Interference Pattern

Overlapping striped layers whose slight angular difference produces a shimmering moire effect -- one of Op Art's most mesmerizing phenomena, implemented in pure CSS.

.op-moire {
  position: relative;
  width: 100%;
  height: 400px;
  overflow: hidden;
  background: var(--op-white);
}

.op-moire__layer-1,
.op-moire__layer-2 {
  position: absolute;
  inset: -50%;
  width: 200%;
  height: 200%;
}

.op-moire__layer-1 {
  background: repeating-linear-gradient(
    0deg,
    var(--op-black) 0px,
    var(--op-black) 2px,
    transparent 2px,
    transparent 6px
  );
  opacity: 0.6;
}

.op-moire__layer-2 {
  background: repeating-linear-gradient(
    3deg,
    var(--op-black) 0px,
    var(--op-black) 2px,
    transparent 2px,
    transparent 6px
  );
  opacity: 0.6;
  animation: op-moire-drift 30s linear infinite;
}

@keyframes op-moire-drift {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(6deg); }
}

Chromatic Vibration Stripes

Alternating complementary-color stripes that produce the retinal vibration effect Op Art is famous for -- the boundary between colors appears to shimmer and buzz.

.op-vibration {
  width: 100%;
  height: 300px;
  background: repeating-linear-gradient(
    0deg,
    var(--op-red) 0px,
    var(--op-red) 4px,
    var(--op-green) 4px,
    var(--op-green) 8px
  );
}

/* Blue-orange variant */
.op-vibration--warm {
  background: repeating-linear-gradient(
    0deg,
    var(--op-blue) 0px,
    var(--op-blue) 4px,
    var(--op-orange) 4px,
    var(--op-orange) 8px
  );
}

/* Violet-yellow variant */
.op-vibration--electric {
  background: repeating-linear-gradient(
    0deg,
    var(--op-violet) 0px,
    var(--op-violet) 4px,
    var(--op-yellow) 4px,
    var(--op-yellow) 8px
  );
}

/* Diagonal variant */
.op-vibration--diagonal {
  background: repeating-linear-gradient(
    45deg,
    var(--op-red) 0px,
    var(--op-red) 4px,
    var(--op-green) 4px,
    var(--op-green) 8px
  );
}

/* Section divider variant: thin band */
.op-vibration-divider {
  width: 100%;
  height: 12px;
  background: repeating-linear-gradient(
    90deg,
    var(--op-black) 0px,
    var(--op-black) 3px,
    var(--op-white) 3px,
    var(--op-white) 6px
  );
}

Checkerboard Warp Effect

A distorted checkerboard that appears to bulge outward from its center, recreating the spherical distortion effect seen in classic Op Art paintings.

.op-checkerboard {
  width: 400px;
  height: 400px;
  margin: 0 auto;
  background:
    repeating-conic-gradient(
      var(--op-black) 0% 25%,
      var(--op-white) 0% 50%
    )
    50% / 40px 40px;
  border-radius: 50%;
  position: relative;
}

/* Creates a lens-like warp illusion via layered radial gradient */
.op-checkerboard::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(
    circle at center,
    transparent 0%,
    transparent 40%,
    rgba(255, 255, 255, 0.3) 70%,
    rgba(255, 255, 255, 0.8) 100%
  );
}

/* Animated scale for pulsating sphere */
.op-checkerboard--pulse {
  animation: op-check-pulse 3s ease-in-out infinite alternate;
}

@keyframes op-check-pulse {
  0% { background-size: 40px 40px; }
  100% { background-size: 32px 32px; }
}

Design Do's and Don'ts

Do's

  • Use optical patterns with intent -- every pattern field should serve a compositional purpose (drawing the eye, creating depth, delineating sections), not merely decorate
  • Provide visual rest zones -- surround high-intensity pattern areas with generous whitespace or solid-color regions so the viewer's eye can recover
  • Maintain razor-sharp edges -- blur and softness destroy the contrast differential that makes Op Art work; keep all pattern boundaries clean and precise
  • Test on multiple screens -- small pixel differences can turn a vibrating pattern into a muddy mess; verify that patterns render crisply on target devices
  • Use animation sparingly -- subtle CSS animation (slow rotation, gentle scaling) amplifies the kinetic illusion; fast or complex animation overwhelms it
  • Pair optical patterns with bold, simple typography -- strong geometric sans-serifs counterbalance the complexity of the pattern fields
  • Consider accessibility -- offer a reduced-motion mode and avoid patterns that are known seizure triggers; respect prefers-reduced-motion
  • Leverage CSS custom properties -- define stripe widths, colors, and animation durations as variables so patterns can be consistently tuned

Don'ts

  • Cover the entire page in optical patterns -- wall-to-wall pattern saturation causes viewer fatigue and discomfort; the effect depends on contrast between patterned and non-patterned zones
  • Use gradients within pattern elements -- Op Art demands flat, solid fills; gradients soften edges and weaken the optical effect
  • Mix too many pattern types -- one or two pattern motifs per page (e.g., concentric circles and parallel stripes) maintain coherence; three or more compete for dominance
  • Ignore motion sensitivity -- rapidly animating or high-frequency patterns can trigger headaches, nausea, or seizures in sensitive individuals; always provide alternatives
  • Introduce decorative serif or script typefaces -- ornamental typography clashes with the mathematical rigor of Op Art and undermines its systematic character
  • Use anti-aliased or blurred pattern edges -- smoothing destroys the precise contrast boundaries that generate the perceptual effect
  • Scale patterns without testing -- a pattern that vibrates beautifully at 4px stripe width may become an indistinct gray blur at 1px on a high-DPI screen
  • Forget the black-and-white foundation -- color Op Art effects (chromatic vibration) are powerful but secondary; the strongest compositions begin with and maintain a strong achromatic structure

Aesthetic Relationship
Bauhaus Shared emphasis on geometric precision, mathematical structure, and the reduction of form to elemental shapes; Bauhaus grid discipline informs Op Art's systematic approach
De Stijl Parallel geometric abstraction movement; De Stijl's strict horizontals, verticals, and primary colors provided a formal vocabulary that Op Art extended into perceptual illusion
Minimalism Both pursue maximum effect from minimal means; Minimalism's reductive philosophy aligns with Op Art's use of simple elements to produce complex perceptual results
Kinetic Typography Kinetic art and Op Art share the goal of creating movement from static forms; kinetic typography applies this principle to letterforms
Psychedelic Psychedelic design borrowed heavily from Op Art's vibrating patterns and chromatic intensity, adding organic forms and countercultural symbolism
Glitch Art Both exploit visual disruption and perceptual confusion as aesthetic tools; Glitch Art's digital artifacts parallel Op Art's analog pattern interference
Space Age Contemporary 1960s movement; shared the era's fascination with science, technology, and perceptual experimentation
Constructivism Precursor movement that established geometric abstraction as a serious artistic language; Op Art inherited its systematic, non-representational approach
Vaporwave Vaporwave's grid distortions and retro-digital aesthetic occasionally channel Op Art's warped geometry through a nostalgic digital lens
Memphis Design Postmodern reaction that borrowed Op Art's bold patterns and high contrast but applied them with playful irreverence rather than mathematical rigor

Quick-Start HTML Template

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Op Art -- Optical Illusion Design</title>
  <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Inter:wght@400;500;700&display=swap" rel="stylesheet">
  <style>
    /* =============================================
       CSS CUSTOM PROPERTIES
       ============================================= */
    :root {
      --op-black: #000000;
      --op-white: #ffffff;
      --op-near-black: #1a1a1a;
      --op-off-white: #f0f0f0;
      --op-gray: #808080;
      --op-charcoal: #333333;
      --op-red: #ff0000;
      --op-green: #00ff00;
      --op-blue: #0000ff;
      --op-orange: #ff8c00;
      --op-violet: #8b00ff;
      --op-yellow: #ffd700;
      --op-cyan: #00ced1;
      --op-hot-pink: #ff1493;
      --op-neon-green: #39ff14;
    }

    /* =============================================
       RESET & BASE
       ============================================= */
    *, *::before, *::after {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      background: var(--op-white);
      color: var(--op-black);
      font-family: 'Inter', sans-serif;
      font-weight: 400;
      line-height: 1.7;
    }

    h1, h2, h3, h4 {
      font-family: 'Space Grotesk', sans-serif;
      font-weight: 700;
      text-transform: uppercase;
      line-height: 1.05;
      letter-spacing: -0.02em;
    }

    a { color: inherit; }

    /* =============================================
       UTILITY: REDUCED MOTION
       ============================================= */
    @media (prefers-reduced-motion: reduce) {
      *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
      }
    }

    /* =============================================
       NAVIGATION
       ============================================= */
    nav {
      display: flex;
      align-items: center;
      justify-content: space-between;
      max-width: 1200px;
      margin: 0 auto;
      padding: 20px 40px;
      border-bottom: 3px solid var(--op-black);
      background: var(--op-white);
      position: sticky;
      top: 0;
      z-index: 100;
    }

    .logo {
      display: flex;
      align-items: center;
      gap: 12px;
      font-family: 'Space Grotesk', sans-serif;
      font-weight: 700;
      font-size: 1.4rem;
      color: var(--op-black);
      text-decoration: none;
      text-transform: uppercase;
      letter-spacing: 0.04em;
    }

    .logo-icon {
      width: 28px;
      height: 28px;
      border-radius: 50%;
      background: repeating-radial-gradient(
        circle,
        var(--op-black) 0px, var(--op-black) 3px,
        var(--op-white) 3px, var(--op-white) 6px
      );
      border: 2px solid var(--op-black);
    }

    nav ul {
      display: flex;
      gap: 28px;
      list-style: none;
    }

    nav ul a {
      font-family: 'Space Grotesk', sans-serif;
      font-weight: 500;
      font-size: 0.85rem;
      color: var(--op-black);
      text-decoration: none;
      text-transform: uppercase;
      letter-spacing: 0.08em;
      position: relative;
      transition: color 0.2s;
    }

    nav ul a::after {
      content: '';
      position: absolute;
      bottom: -4px;
      left: 0;
      width: 100%;
      height: 3px;
      background: repeating-linear-gradient(
        90deg,
        var(--op-black) 0px, var(--op-black) 2px,
        transparent 2px, transparent 4px
      );
      transform: scaleX(0);
      transition: transform 0.3s ease;
    }

    nav ul a:hover::after {
      transform: scaleX(1);
    }

    /* =============================================
       HERO SECTION
       ============================================= */
    .hero {
      position: relative;
      min-height: 90vh;
      display: flex;
      align-items: center;
      justify-content: center;
      background: var(--op-black);
      overflow: hidden;
    }

    .hero-pattern {
      position: absolute;
      inset: 0;
      background: repeating-conic-gradient(
        var(--op-black) 0deg 5deg,
        var(--op-white) 5deg 10deg
      );
      background-position: center;
      opacity: 0.12;
      animation: hero-rotate 60s linear infinite;
    }

    @keyframes hero-rotate {
      0% { transform: rotate(0deg) scale(1.5); }
      100% { transform: rotate(360deg) scale(1.5); }
    }

    .hero-content {
      position: relative;
      z-index: 2;
      text-align: center;
      max-width: 800px;
      padding: 60px 48px;
      background: rgba(0, 0, 0, 0.88);
      border: 2px solid rgba(255, 255, 255, 0.15);
    }

    .hero h1 {
      font-size: clamp(2.8rem, 8vw, 6rem);
      color: var(--op-white);
      margin-bottom: 1.25rem;
      letter-spacing: -0.03em;
      line-height: 0.95;
    }

    .hero h1 .accent {
      background: linear-gradient(90deg, var(--op-red), var(--op-hot-pink));
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      background-clip: text;
    }

    .hero p {
      font-size: 1.15rem;
      color: var(--op-off-white);
      max-width: 500px;
      margin: 0 auto 2rem;
      line-height: 1.7;
    }

    .btn {
      display: inline-block;
      background: var(--op-white);
      color: var(--op-black);
      border: 3px solid var(--op-white);
      padding: 14px 40px;
      font-family: 'Space Grotesk', sans-serif;
      font-weight: 700;
      font-size: 0.9rem;
      text-transform: uppercase;
      letter-spacing: 0.1em;
      text-decoration: none;
      cursor: pointer;
      position: relative;
      overflow: hidden;
      transition: background 0.3s, color 0.3s;
    }

    .btn:hover {
      background: transparent;
      color: var(--op-white);
    }

    .btn--dark {
      background: var(--op-black);
      color: var(--op-white);
      border-color: var(--op-black);
    }

    .btn--dark:hover {
      background: transparent;
      color: var(--op-black);
    }

    /* =============================================
       STRIPE DIVIDER
       ============================================= */
    .stripe-divider {
      width: 100%;
      height: 12px;
      background: repeating-linear-gradient(
        90deg,
        var(--op-black) 0px, var(--op-black) 3px,
        var(--op-white) 3px, var(--op-white) 6px
      );
    }

    .stripe-divider--color {
      background: repeating-linear-gradient(
        90deg,
        var(--op-red) 0px, var(--op-red) 4px,
        var(--op-green) 4px, var(--op-green) 8px
      );
    }

    /* =============================================
       ABOUT SECTION
       ============================================= */
    .about {
      max-width: 1200px;
      margin: 0 auto;
      padding: 100px 40px;
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 60px;
      align-items: center;
    }

    .about h2 {
      font-size: 2.5rem;
      margin-bottom: 1.5rem;
    }

    .about p {
      font-size: 1rem;
      color: var(--op-charcoal);
      margin-bottom: 1rem;
      line-height: 1.8;
    }

    .concentric-ring {
      width: 100%;
      max-width: 380px;
      aspect-ratio: 1;
      border-radius: 50%;
      background: repeating-radial-gradient(
        circle at center,
        var(--op-black) 0px, var(--op-black) 8px,
        var(--op-white) 8px, var(--op-white) 16px
      );
      margin: 0 auto;
      animation: ring-pulse 4s ease-in-out infinite alternate;
    }

    @keyframes ring-pulse {
      0% { transform: scale(1); }
      100% { transform: scale(1.04); }
    }

    /* =============================================
       FEATURES / CARDS
       ============================================= */
    .features {
      background: var(--op-off-white);
      padding: 100px 0;
      border-top: 3px solid var(--op-black);
      border-bottom: 3px solid var(--op-black);
    }

    .features-header {
      max-width: 1200px;
      margin: 0 auto;
      padding: 0 40px 60px;
    }

    .features-header h2 {
      font-size: 2.5rem;
    }

    .features-header p {
      font-size: 1.05rem;
      color: var(--op-charcoal);
      margin-top: 0.75rem;
      max-width: 600px;
    }

    .features-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      gap: 32px;
      max-width: 1200px;
      margin: 0 auto;
      padding: 0 40px;
    }

    .card {
      background: var(--op-white);
      border: 3px solid var(--op-black);
      overflow: hidden;
      transition: transform 0.3s ease;
    }

    .card:hover {
      transform: translateY(-4px);
    }

    .card-stripe {
      height: 8px;
      background: repeating-linear-gradient(
        90deg,
        var(--op-black) 0px, var(--op-black) 4px,
        var(--op-white) 4px, var(--op-white) 8px
      );
    }

    .card:nth-child(2) .card-stripe {
      background: repeating-linear-gradient(
        90deg,
        var(--op-red) 0px, var(--op-red) 4px,
        var(--op-green) 4px, var(--op-green) 8px
      );
    }

    .card:nth-child(3) .card-stripe {
      background: repeating-linear-gradient(
        90deg,
        var(--op-blue) 0px, var(--op-blue) 4px,
        var(--op-orange) 4px, var(--op-orange) 8px
      );
    }

    .card-body {
      padding: 32px;
    }

    .card-body h3 {
      font-size: 1.15rem;
      margin-bottom: 0.75rem;
    }

    .card-body p {
      font-size: 0.95rem;
      color: var(--op-charcoal);
      line-height: 1.6;
    }

    /* =============================================
       ILLUSION GALLERY
       ============================================= */
    .gallery {
      background: var(--op-black);
      color: var(--op-white);
      padding: 100px 0;
    }

    .gallery-header {
      max-width: 1200px;
      margin: 0 auto;
      padding: 0 40px 60px;
      text-align: center;
    }

    .gallery-header h2 {
      font-size: 2.5rem;
      margin-bottom: 0.75rem;
    }

    .gallery-header p {
      color: var(--op-gray);
      font-size: 1.05rem;
    }

    .gallery-grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 24px;
      max-width: 1200px;
      margin: 0 auto;
      padding: 0 40px;
    }

    .illusion {
      aspect-ratio: 1;
      border: 2px solid rgba(255, 255, 255, 0.2);
      overflow: hidden;
      position: relative;
    }

    /* Illusion 1: Concentric rings */
    .illusion--rings {
      border-radius: 0;
      background: repeating-radial-gradient(
        circle at center,
        var(--op-white) 0px, var(--op-white) 6px,
        var(--op-black) 6px, var(--op-black) 12px
      );
    }

    /* Illusion 2: Checkerboard */
    .illusion--checker {
      background:
        repeating-conic-gradient(
          var(--op-white) 0% 25%,
          var(--op-black) 0% 50%
        )
        50% / 30px 30px;
    }

    /* Illusion 3: Moire lines */
    .illusion--moire {
      background: var(--op-white);
    }

    .illusion--moire::before,
    .illusion--moire::after {
      content: '';
      position: absolute;
      inset: -25%;
      width: 150%;
      height: 150%;
    }

    .illusion--moire::before {
      background: repeating-linear-gradient(
        0deg,
        var(--op-black) 0px, var(--op-black) 2px,
        transparent 2px, transparent 5px
      );
      opacity: 0.7;
    }

    .illusion--moire::after {
      background: repeating-linear-gradient(
        4deg,
        var(--op-black) 0px, var(--op-black) 2px,
        transparent 2px, transparent 5px
      );
      opacity: 0.7;
    }

    /* Illusion 4: Radial sunburst */
    .illusion--sunburst {
      background: repeating-conic-gradient(
        var(--op-white) 0deg 6deg,
        var(--op-black) 6deg 12deg
      );
    }

    /* Illusion 5: Chromatic red-green stripes */
    .illusion--chromatic {
      background: repeating-linear-gradient(
        0deg,
        var(--op-red) 0px, var(--op-red) 4px,
        var(--op-green) 4px, var(--op-green) 8px
      );
    }

    /* Illusion 6: Violet-yellow vibration */
    .illusion--vibration {
      background: repeating-linear-gradient(
        45deg,
        var(--op-violet) 0px, var(--op-violet) 4px,
        var(--op-yellow) 4px, var(--op-yellow) 8px
      );
    }

    /* =============================================
       STATEMENT / CTA SECTION
       ============================================= */
    .statement {
      text-align: center;
      padding: 100px 40px;
      background: var(--op-white);
      position: relative;
    }

    .statement h2 {
      font-size: clamp(2rem, 5vw, 3.5rem);
      margin-bottom: 1.5rem;
    }

    .statement p {
      font-size: 1.1rem;
      color: var(--op-charcoal);
      max-width: 560px;
      margin: 0 auto 2rem;
      line-height: 1.7;
    }

    /* =============================================
       FOOTER
       ============================================= */
    footer {
      background: var(--op-black);
      color: var(--op-gray);
      text-align: center;
      padding: 40px;
      font-size: 0.85rem;
      border-top: 3px solid var(--op-charcoal);
    }

    footer a {
      color: var(--op-white);
      text-decoration: none;
    }

    footer a:hover {
      text-decoration: underline;
    }

    /* =============================================
       RESPONSIVE
       ============================================= */
    @media (max-width: 768px) {
      nav {
        padding: 16px 24px;
      }

      nav ul {
        gap: 16px;
      }

      .hero {
        min-height: 70vh;
      }

      .hero-content {
        padding: 40px 24px;
      }

      .about {
        grid-template-columns: 1fr;
        padding: 60px 24px;
        gap: 40px;
      }

      .about .concentric-ring {
        max-width: 280px;
      }

      .features-header,
      .features-grid {
        padding-left: 24px;
        padding-right: 24px;
      }

      .gallery-grid {
        grid-template-columns: repeat(2, 1fr);
        padding: 0 24px;
      }

      .gallery-header {
        padding: 0 24px 40px;
      }

      .statement {
        padding: 60px 24px;
      }
    }

    @media (max-width: 480px) {
      nav ul {
        display: none;
      }

      .gallery-grid {
        grid-template-columns: 1fr;
      }
    }
  </style>
</head>
<body>

  <!-- Navigation -->
  <nav>
    <a href="#" class="logo">
      <div class="logo-icon"></div>
      Op Art
    </a>
    <ul>
      <li><a href="#about">About</a></li>
      <li><a href="#principles">Principles</a></li>
      <li><a href="#gallery">Gallery</a></li>
      <li><a href="#contact">Contact</a></li>
    </ul>
  </nav>

  <!-- Hero Section -->
  <section class="hero">
    <div class="hero-pattern"></div>
    <div class="hero-content">
      <h1>See the <span class="accent">Illusion</span></h1>
      <p>Geometric precision meets perceptual phenomenon.
         Static patterns that move, flat surfaces that breathe,
         and simple forms that confound the eye.</p>
      <a href="#about" class="btn">Explore</a>
    </div>
  </section>

  <!-- Stripe Divider -->
  <div class="stripe-divider"></div>

  <!-- About Section -->
  <section class="about" id="about">
    <div>
      <h2>Perception Is the Medium</h2>
      <p>Op Art exploits the mechanics of human vision to produce
         illusions of movement, vibration, and depth from entirely
         flat, static surfaces. Rooted in the 1960s experiments of
         Bridget Riley and Victor Vasarely, it transforms mathematical
         precision into perceptual poetry.</p>
      <p>Every stripe width, every color adjacency, every geometric
         interval is calculated to trigger specific responses in the
         viewer's visual cortex. The artwork is completed not on the
         canvas, but inside the eye.</p>
    </div>
    <div class="concentric-ring"></div>
  </section>

  <!-- Chromatic Divider -->
  <div class="stripe-divider--color"></div>

  <!-- Features Section -->
  <section class="features" id="principles">
    <div class="features-header">
      <h2>Principles</h2>
      <p>The foundations of optical art, translated to digital design.</p>
    </div>
    <div class="features-grid">
      <div class="card">
        <div class="card-stripe"></div>
        <div class="card-body">
          <h3>Contrast</h3>
          <p>Maximum luminance and chromatic differentials drive
             every optical effect. Black against white. Red against
             green. The boundary is where the illusion lives.</p>
        </div>
      </div>
      <div class="card">
        <div class="card-stripe"></div>
        <div class="card-body">
          <h3>Repetition</h3>
          <p>A single line is inert. A thousand lines at precise
             intervals vibrate with apparent motion. Pattern rhythm
             is the engine of Op Art's kinetic energy.</p>
        </div>
      </div>
      <div class="card">
        <div class="card-stripe"></div>
        <div class="card-body">
          <h3>Precision</h3>
          <p>Every angle, spacing, and proportion is mathematically
             determined. There is no room for approximation -- the
             optical effect depends on absolute geometric control.</p>
        </div>
      </div>
    </div>
  </section>

  <!-- Stripe Divider -->
  <div class="stripe-divider"></div>

  <!-- Illusion Gallery -->
  <section class="gallery" id="gallery">
    <div class="gallery-header">
      <h2>Optical Gallery</h2>
      <p>Six fundamental Op Art patterns rendered in pure CSS.</p>
    </div>
    <div class="gallery-grid">
      <div class="illusion illusion--rings"></div>
      <div class="illusion illusion--checker"></div>
      <div class="illusion illusion--moire"></div>
      <div class="illusion illusion--sunburst"></div>
      <div class="illusion illusion--chromatic"></div>
      <div class="illusion illusion--vibration"></div>
    </div>
  </section>

  <!-- Statement Section -->
  <section class="statement" id="contact">
    <h2>The Eye Completes the Art</h2>
    <p>Op Art reminds us that design is not just what we put on
       the screen -- it is what happens in the space between the
       screen and the mind. Perception is participation.</p>
    <a href="#" class="btn btn--dark">Get Started</a>
  </section>

  <!-- Footer -->
  <footer>
    <p>Built on Op Art principles. Vasarely 1938 -- Riley 1961 -- The Responsive Eye 1965.</p>
  </footer>

</body>
</html>

Implementation Tips

  • Respect prefers-reduced-motion -- always wrap Op Art animations in a media query check; disable rotation, pulsing, and moire drift for users who request reduced motion, as optical patterns can trigger vestibular discomfort or photosensitive seizures
  • Define stripe widths as CSS custom properties -- a single --op-stripe-width variable lets you tune pattern density globally, making it easy to adjust for different screen densities and user preferences
  • Use repeating-linear-gradient and repeating-radial-gradient for pattern generation -- these CSS functions are hardware-accelerated and produce crisp, resolution-independent patterns without image assets
  • Test patterns at actual device pixel ratios -- a 4px stripe that vibrates on a 1x display may alias into gray mush on a 3x Retina screen; use @media (-webkit-min-device-pixel-ratio: 2) to adjust stripe widths for high-DPI
  • Layer patterns with opacity control -- rather than showing raw high-contrast patterns at full intensity (which can be overwhelming), layer them beneath content at 10-20% opacity for textured backgrounds that suggest the aesthetic without assaulting the viewer
  • Contain pattern animations to GPU-composited properties -- animate transform and opacity rather than background-position or background-size to maintain smooth 60fps performance, especially on mobile
  • Provide a "calm mode" toggle -- for content-heavy Op Art sites, consider a UI toggle that replaces animated patterns with static solid fills, giving users control over visual intensity
  • Keep content zones pattern-free -- overlay text and interactive elements on solid or semi-transparent backgrounds within pattern sections; never place body text directly on top of an active optical pattern, as legibility will suffer dramatically
Agence WagnerAgence Wagner

© 2026 Agence Wagner. All rights reserved.

Designs from chrislemke/website_designs, licensed under MIT.