Menu

Tailwind CSS Invert

The invert filter property is used to invert the colors of an element, switching light colors to dark colors and vice versa. This can be highly valuable for designing themes, enhancing accessibility, or creating custom effects like "dark modes." Tailwind CSS provides utilities to apply and manage the invert property easily, helping you create stunning visual effects efficiently and responsively.

ClassPropertiesExample
invert-0filter: invert(0);<div className="invert-0"></div>
invertfilter: invert(100%);<div className="invert"></div>

Overview of Invert

Adding the Invert

To apply the invert filter to your component, use invert utility class.

This is a live editor. Play around with it!
// JSX example with Tailwind CSS classes
const InvertDemo = () => {
  return (
    <div className="h-screen w-screen flex flex-col gap-4 justify-center items-center bg-gray-100">
      <p className="text-lg font-semibold">Default vs inverted image</p>
      {/* Non-inverted image */}
      <img
        src="https://images.unsplash.com/photo-1511467687858-23d96c32e4ae"
        alt="Default"
        className="rounded-md m-4 h-28"
      />
      {/* Inverted image */}
      <img
        src="https://images.unsplash.com/photo-1511467687858-23d96c32e4ae"
        alt="Inverted"
        className="invert rounded-md m-4 h-28"
      />
    </div>
  );
};

export default InvertDemo;

// CSS explanation:
// img: Applies a default non-inverted style versus an inverted style.
// h-screen & w-screen: Full-height and full-width layout.

Removing the Filter

If you need to remove the inversion, use the invert-0 class. To remove all the applied filters, use filter-none utility.

This is a live editor. Play around with it!
const ResetInvert = () => {
  return (
    <div className="h-screen w-screen flex flex-col justify-center items-center bg-white">
      {/* Reset inversion */}
      <img
        src="https://images.unsplash.com/photo-1511467687858-23d96c32e4ae"
        alt="Default"
        className="invert-0 rounded-md h-28"
      />
    </div>
  );
};

export default ResetInvert;

// CSS explanation:
// invert-0: Explicitly disables any filter inversion on the second image.

States and Responsiveness

Modern web development often relies on interactions or responsive designs. Tailwind CSS support them with state and responsive modifiers. You can pair invert with pseudo-classes or breakpoints to conditionally apply and customize its behavior.

Hover and Focus States

By combining the hover or focus prefixes with invert, you can trigger the effect dynamically.

This is a live editor. Play around with it!
const HoverInvert = () => {
  return (
    <div className="h-screen w-screen flex gap-4 flex-col gap-8 justify-center items-center">
      <p className="text-lg font-semibold px-20 text-center">Hover on the below image to invert it</p>
      <img
        src="https://images.unsplash.com/photo-1511467687858-23d96c32e4ae"
        alt="Hover Me"
        className="rounded-md hover:invert transition duration-300 h-32"
      />
    </div>
  );
};

export default HoverInvert;

// CSS explanation:
// hover:invert: Enables inversion when an image is hovered.

Breakpoint Modifiers

Tailwind's breakpoint utilities empower you to apply invert dynamically across screen sizes. This makes designing responsive themes incredibly simple.

This is a live editor. Play around with it!
const ResponsiveInvert = () => {
  return (
    <div className="h-screen w-screen flex gap-4 flex-col gap-8 justify-center items-center">
      <p className="text-lg font-semibold px-12 text-center">The below image will invert based on the screen</p>
      {/* Non-inverted on small screens, inverted on larger screens */}
      <img
        src="https://images.unsplash.com/photo-1511467687858-23d96c32e4ae"
        alt="Responsive"
        className="rounded-md sm:invert-0 md:invert h-32"
      />
    </div>
  );
};

export default ResponsiveInvert;

// CSS explanation:
// sm:invert-0: No inversion by default (small screens).
// md:invert: Applies inversion starting at medium breakpoints.

Custom Invert

Tailwind also allows you to customize invert values or use custom arbitrary values to achieve your perfect design.

Extending the Theme

Tailwind’s configuration file (tailwind.config.js) can be extended to include custom invert values. After configuring, use the newly extended classes in your components:

This is a live editor. Play around with it!
import tailwindConfig from "./tailwind.config.js";
tailwind.config = tailwindConfig;

const CustomInvert = () => {
  return (
    <div className="h-screen w-screen flex gap-4 flex-col gap-4 justify-center items-center">
      <p className="text-lg font-semibold px-12 text-center">The below images have custom invert values</p>
      {/* Apply 25% inversion */}
      <img
        src="https://images.unsplash.com/photo-1511467687858-23d96c32e4ae"
        alt="25% Inverted"
        className="invert-25 rounded-md h-32"
      />

      {/* Apply 75% inversion */}
      <img
        src="https://images.unsplash.com/photo-1511467687858-23d96c32e4ae"
        alt="75% Inverted"
        className="invert-75 rounded-md h-32"
      />
    </div>
  );
};

export default CustomInvert;

// CSS explanation:
// invert-25: Custom partial inversion defined in the extended theme.
// invert-75: Higher inversion intensity for the second image.

Using Arbitrary Values

Instead of modifying the Tailwind configuration file, you can also use arbitrary values for one-off cases.

This is a live editor. Play around with it!
const ArbitraryInvert = () => {
  return (
    <div className="h-screen w-screen flex gap-4 flex-col gap-8 justify-center items-center">
      <p className="text-lg font-semibold px-12 text-center">The below image has an arbitrary invert value</p>
      {/* Custom arbitrary value for inversion */}
      <img
        src="https://images.unsplash.com/photo-1511467687858-23d96c32e4ae"
        alt="Custom"
        className="rounded-md invert-[0.6] h-32"
      />
    </div>
  );
};

export default ArbitraryInvert;

// CSS explanation:
// invert-[0.6]: Custom inline inversion set to 60%.

Real World Examples

Photo gallery where images invert their colors on hover, creating an artistic effect for a photography portfolio.

This is a live editor. Play around with it!
export default function PhotoGallery() {
  const photos = [
    {
      src: "https://images.unsplash.com/photo-1682687220945-922198770e60",
      alt: "Urban landscape at night",
      title: "City Lights"
    },
    {
      src: "https://images.unsplash.com/photo-1682687220199-d0124f48f95b",
      alt: "Ocean waves crashing",
      title: "Ocean Waves"
    },
    {
      src: "https://images.unsplash.com/photo-1682687220795-796d3f6f7000",
      alt: "Desert sand dunes",
      title: "Desert Sands"
    },
    {
      src: "https://images.unsplash.com/photo-1682687220509-61b8a906ca19",
      alt: "Forest canopy",
      title: "Forest Dreams"
    },
    {
      src: "https://images.unsplash.com/photo-1682687220923-c58b9a4592ae",
      alt: "Northern lights",
      title: "Aurora"
    }
  ];

  return (
    <div className="grid grid-cols-2 md:grid-cols-3 gap-4 p-6">
      {photos.map((photo, index) => (
        <div key={index} className="relative group">
          <img
            src={photo.src}
            alt={photo.alt}
            className="w-full h-64 object-cover transition-all duration-300 group-hover:invert"
          />
          <h3 className="absolute bottom-4 left-4 text-white text-xl font-bold">
            {photo.title}
          </h3>
        </div>
      ))}
    </div>
  );
}

Social Media Profile Cards with Dark Mode Invert

Profile cards that use invert for dark mode compatibility, showing social media influencer profiles.

This is a live editor. Play around with it!
export default function ProfileCards() {
  const profiles = [
    {
      name: "Sarah Chen",
      avatar: "https://images.unsplash.com/photo-1682687220015-186f63b8850a",
      followers: "89K",
      profession: "Food Blogger",
      platform: "YouTube"
    },
  ];

  return (
    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 p-8 bg-gray-100 h-screen dark:bg-gray-800">
      {profiles.map((profile, index) => (
        <div key={index} className="bg-white rounded-xl p-6 shadow-lg transform hover:scale-105 transition-all h-72">
          <img
            src={profile.avatar}
            alt={profile.name}
            className="w-24 h-24 rounded-full mx-auto mb-4 dark:invert"
          />
          <h3 className="text-xl font-bold text-center mb-2">{profile.name}</h3>
          <p className="text-gray-600 text-center">{profile.profession}</p>
          <p className="text-blue-500 text-center mt-2">{profile.platform}</p>
          <p className="text-gray-800 font-bold text-center mt-2">{profile.followers} followers</p>
        </div>
      ))}
    </div>
  );
}

Night Mode Map

Map interface with invert functionality for better nighttime visibility.

This is a live editor. Play around with it!
const NightModeMap = () => {
  const mapLocations = [
    {
      name: "Central Park",
      type: "Park",
      coordinates: "40.7829° N, 73.9654° W"
    },
    {
      name: "Times Square",
      type: "Landmark",
      coordinates: "40.7580° N, 73.9855° W"
    },
    {
      name: "Brooklyn Bridge",
      type: "Bridge",
      coordinates: "40.7061° N, 73.9969° W"
    },
    {
      name: "Empire State",
      type: "Building",
      coordinates: "40.7484° N, 73.9857° W"
    },
    {
      name: "High Line",
      type: "Park",
      coordinates: "40.7480° N, 74.0048° W"
    },
    {
      name: "Battery Park",
      type: "Park",
      coordinates: "40.7032° N, 74.0171° W"
    }
  ];

  return (
    <div className="rounded-lg bg-gray-100 p-4">
      <div className="mb-4 flex items-center justify-between">
        <h3 className="text-lg font-bold">NYC Tourist Spots</h3>
      </div>
      <div className="group relative h-96 overflow-hidden rounded-lg">
        <div className="absolute right-4 top-4 z-10 space-y-2">
          {mapLocations.map((location) => (
            <button
              key={location.name}
              className="block w-full rounded bg-white px-4 py-[6px] text-left text-sm shadow-lg transition-all duration-300 hover:invert"
            >
              <strong>{location.name}</strong>
              <br />
              <span className="text-xs text-gray-600">{location.coordinates}</span>
            </button>
          ))}
        </div>
        <div className="h-full w-full transition-all duration-500 group-hover:invert">
          <img
            src="https://images.unsplash.com/photo-1534270804882-6b5048b1c1fc"
            className="absolute h-full w-full object-cover"
          />
        </div>
      </div>
    </div>
  );
};

export default NightModeMap;

Film strip-style image gallery with invert effect to mimic negative film properties.

This is a live editor. Play around with it!
const FilmStripGallery = () => {
  const photographs = [
    {
      title: "Street Life",
      src: "https://images.unsplash.com/photo-1477959858617-67f85cf4f1df",
      alt: "Black and white street photography",
      year: "2023"
    },
    {
      title: "Urban Abstract",
      src: "https://images.unsplash.com/photo-1480714378408-67cf0d13bc1b",
      alt: "Abstract urban architecture",
      year: "2023"
    },
    {
      title: "Portrait Study",
      src: "https://images.unsplash.com/photo-1544005313-94ddf0286df2",
      alt: "Black and white portrait",
      year: "2023"
    },
    {
      title: "City Nights",
      src: "https://images.unsplash.com/photo-1519501025264-65ba15a82390",
      alt: "Night time city photography",
      year: "2023"
    },
  ];

  return (
    <div className="space-y-4 bg-black p-4">
      {photographs.map((photo) => (
        <div 
          key={photo.title}
          className="group relative"
        >
          <img
            src={photo.src}
            alt={photo.alt}
            className="h-48 w-full object-cover opacity-80 transition-all duration-500 hover:invert"
          />
          <div className="absolute bottom-4 left-4 text-white">
            <h3 className="text-lg font-bold">{photo.title}</h3>
            <p className="text-sm opacity-75">{photo.year}</p>
          </div>
        </div>
      ))}
    </div>
  );
};

export default FilmStripGallery;

Feature Showcase Cards

Interactive feature cards that invert colors on hover, highlighting key product features.

This is a live editor. Play around with it!
const FeatureShowcase = () => {
  const features = [
    {
      title: "Cloud Storage",
      description: "Secure and scalable storage solutions for your data",
      icon: "https://images.unsplash.com/photo-1590859808308-3d2d9c515b1a",
      alt: "Cloud storage icon"
    },
    {
      title: "Analytics",
      description: "Advanced data analytics and visualization tools",
      icon: "https://images.unsplash.com/photo-1551288049-bebda4e38f71",
      alt: "Analytics icon"
    },
    {
      title: "Security",
      description: "Enterprise-grade security and encryption",
      icon: "https://images.unsplash.com/photo-1563986768494-4dee2763ff3f",
      alt: "Security icon"
    },
    {
      title: "Integration",
      description: "Seamless integration with popular platforms",
      icon: "https://images.unsplash.com/photo-1451187580459-43490279c0fa",
      alt: "Integration icon"
    },
    {
      title: "Support",
      description: "24/7 dedicated customer support",
      icon: "https://images.unsplash.com/photo-1512314889357-e157c22f938d",
      alt: "Support icon"
    },
    {
      title: "Automation",
      description: "Powerful workflow automation tools",
      icon: "https://images.unsplash.com/photo-1518432031352-d6fc5c10da5a",
      alt: "Automation icon"
    }
  ];

  return (
    <div className="grid grid-cols-2 gap-4 p-4">
      {features.map((feature) => (
        <div
          key={feature.title}
          className="group rounded-xl bg-gray-100 p-6 transition-all duration-300 hover:invert"
        >
          <img 
            src={feature.icon}
            alt={feature.alt}
            className="mb-4 h-12 w-12 rounded-lg object-cover"
          />
          <h3 className="mb-2 text-lg font-bold">{feature.title}</h3>
          <p className="text-sm text-gray-600">{feature.description}</p>
        </div>
      ))}
    </div>
  );
};

export default FeatureShowcase;

Customization Examples

Image gallery with custom invert filters.

This is a live editor. Play around with it!
import tailwindConfig from "./tailwind.config.js";
tailwind.config = tailwindConfig;

// App.js
export default function PhotoGallery() {
  return (
    <div className="grid gap-4 p-8 bg-gray-900">
      <div className="group relative overflow-hidden rounded-lg h-72">
        <img
          src="https://images.unsplash.com/photo-1539634262233-7c0b48ab9503"
          className="w-full h-full object-cover transition-all duration-300 group-hover:invert-35"
          alt="Nature"
        />
        <div className="absolute bottom-0 p-4 text-white opacity-0 group-hover:opacity-100 transition-opacity">
          <h3 className="text-lg font-bold">Subtle Invert</h3>
        </div>
      </div>
      <div className="group relative overflow-hidden rounded-lg">
        <img
          src="https://images.unsplash.com/photo-1539634262233-7c0b48ab9503"
          className="w-full h-64 object-cover transition-all duration-300 group-hover:invert-65"
          alt="Urban"
        />
        <div className="absolute bottom-0 p-4 text-white opacity-0 group-hover:opacity-100 transition-opacity">
          <h3 className="text-lg font-bold">Medium Invert</h3>
        </div>
      </div>
      <div className="group relative overflow-hidden rounded-lg">
        <img
          src="https://images.unsplash.com/photo-1539634262233-7c0b48ab9503"
          className="w-full h-64 object-cover transition-all duration-300 group-hover:invert-85"
          alt="Abstract"
        />
        <div className="absolute bottom-0 p-4 text-white opacity-0 group-hover:opacity-100 transition-opacity">
          <h3 className="text-lg font-bold">Strong Invert</h3>
        </div>
      </div>
    </div>
  )
}

Background Inversion Hero Section

Hero section with inverted background on scroll.

This is a live editor. Play around with it!
import tailwindConfig from "./tailwind.config.js";
tailwind.config = tailwindConfig;

// App.js
import React, { useState, useEffect } from 'react';

const HeroSection = () => {
  const [scrolled, setScrolled] = useState(false);

  useEffect(() => {
    const handleScroll = () => {
      setScrolled(window.scrollY > 50);
    };
    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  return (
    <div className="h-[700px] relative">
      <div className="fixed inset-0">
        <img
          src="https://images.unsplash.com/photo-1682687220363-35e4621ed990"
          alt="Hero background"
          className={`w-full h-full object-cover ${scrolled ? 'invert-text' : ''}`}
        />
      </div>
      
      <div className="relative z-10 flex items-center justify-center min-h-screen
        transition-all duration-500">
        <div className="text-center">
          <h1 className="text-6xl font-bold text-white mb-4">Welcome to the Future</h1>
          <p className="text-xl text-white opacity-90">Scroll to see the inversion effect</p>
        </div>
      </div>
    </div>
  );
};

export default HeroSection;

Night Mode Text Editor

Text editor with different inversion modes.

This is a live editor. Play around with it!
import tailwindConfig from "./tailwind.config.js";
tailwind.config = tailwindConfig;

// App.js
import React, { useState } from 'react';

const TextEditor = () => {
  const [viewMode, setViewMode] = useState('default');
  const [fontSize, setFontSize] = useState(16);
  const [lineHeight, setLineHeight] = useState(1.6);

  return (
    <div className="min-h-screen bg-gray-100 p-8">
      <div className="max-w-5xl mx-auto">
        <div className="bg-white rounded-xl shadow-lg p-6">
          <div className="mb-6">
            <div className="flex flex-wrap gap-4 mb-6">
              {['default', 'night', 'sepia', 'paper', 'dark'].map(mode => (
                <button
                  key={mode}
                  onClick={() => setViewMode(mode)}
                  className={`px-3 py-2 rounded-lg capitalize ${
                    viewMode === mode 
                      ? 'bg-blue-600 text-white' 
                      : 'bg-gray-200'
                  }`}
                >
                  {mode}
                </button>
              ))}
            </div>

            <div className="flex gap-4 items-center">
              <div className="flex items-center gap-2">
                <span className="text-sm">Font Size:</span>
                <select
                  value={fontSize}
                  onChange={(e) => setFontSize(Number(e.target.value))}
                  className="border rounded px-2 py-1"
                >
                  {[12, 14, 16, 18, 20, 24].map(size => (
                    <option key={size} value={size}>{size}px</option>
                  ))}
                </select>
              </div>

              <div className="flex items-center gap-2">
                <span className="text-sm">Line Height:</span>
                <select
                  value={lineHeight}
                  onChange={(e) => setLineHeight(Number(e.target.value))}
                  className="border rounded px-2 py-1"
                >
                  {[1.4, 1.6, 1.8, 2.0].map(height => (
                    <option key={height} value={height}>{height}</option>
                  ))}
                </select>
              </div>
            </div>
          </div>

          <div 
            className={`rounded-lg p-6 transition-all duration-300
              ${viewMode === 'night' ? 'bg-gray-900 invert-night text-white' : ''}
              ${viewMode === 'sepia' ? 'bg-yellow-50 invert-sepia' : ''}
              ${viewMode === 'paper' ? 'bg-white invert-paper' : ''}
              ${viewMode === 'dark' ? 'bg-gray-800 invert-dark text-white' : ''}
              ${viewMode === 'default' ? 'bg-white invert-default' : ''}`}
          >
            <textarea
              className="w-full h-[500px] focus:outline-none bg-transparent"
              style={{
                fontSize: `${fontSize}px`,
                lineHeight: lineHeight
              }}
              placeholder="Start typing your content here..."
            />
          </div>
        </div>
      </div>
    </div>
  );
};

export default TextEditor;

Best Practices

Maintain Design Consistency

Consistency plays a critical role in building a consistent user experience, and this principle applies strongly when using the invert utility in Tailwind CSS. To ensure a uniform look and feel across your application, define a clear design system that determines where and when to apply inversion. For instance, if you’re implementing a dark mode interface, decide on consistent rules for which elements (text, images, icons) should use inversion and under what conditions. Tailwind’s built-in modifiers like dark: or hover: provide excellent tools to enforce these rules.

Structured configurations in the tailwind.config.js file can also help maintain consistency. By extending the theme with custom inversion values (e.g., invert-25, invert-75), you can use semantic classes to express uniform visual intent across components. For example, defining invert-75 as a secondary visual effect for dimming specific UI areas ensures reuse throughout the project.

Optimize for Reusability

Instead of hardcoding inversion directly into each instance, consider creating reusable container components with predefined classes. This ensures scalability and reduces redundant configurations, especially in large-scale applications. For example, you could create a Card component and dynamically pass inversion classes via props to handle dark or light modes.

Reuse also applies to extending Tailwind’s configuration for global invert variants. Customizing values like invert-50 and invert-90 in the tailwind.config.js lets you unify styling behaviors across potentially hundreds of components, reducing inconsistencies as the project scales.

Accessibility Considerations

Enhance Readability and Navigability

Inversion can significantly affect content readability, so it is vital to ensure text and images remain distinguishable after applying the effect.

Tailwind’s utility classes like invert can sometimes interfere with white-on-black or black-on-white designs, so balancing their usage based on context is important.

Test your visuals frequently with tools like color contrast analyzers or screen reader software to ensure designs remain accessible across edge cases.

Focus on High Contrast

Inverting images or icons can create contrasts that may obscure other nearby elements, especially when paired with dark backgrounds. When designing for high contrast, always validate that the inversion effect complements the surrounding theme while maintaining sufficient separation from the background.

Using opacity, shadows, contrast utilities, etc. ensures interactive components remain distinguishable.