Tailwind CSS List Style Image
When working with unordered and ordered lists, the list-style-image
property in CSS allows you to replace the default bullet or number markers with a custom image. This property comes in handy when designing lists with a custom aesthetic that aligns with a brand's visual guidelines.
In this article, we'll explore the various ways to implement and customize list styles in Tailwind CSS, with step-by-step instructions.
Class | Properties | Example |
---|---|---|
list-image-none | list-style-image: none; | <div className="list-image-none"></div> |
Overview of List Style Image
Adding the List Style Image
You can use the list-image-*
utility classes in Tailwind CSS to assign a custom image to list elements. Tailwind integrates seamlessly with the list-style-image
property in to handle custom markers. Here's how to assign an external image as a stylish bullet for a list.
export default function StyledList() { return ( <div className="w-screen h-screen flex items-center justify-center bg-gray-100"> <ul className="list-image-[url('https://images.unsplash.com/photo-1517059224940-d4af9eec41b7?w=20')] list-disc pl-6 space-y-3"> {/* Custom image for bullets */} <li className="text-lg text-gray-800">First list item</li> <li className="text-lg text-gray-800">Second list item</li> <li className="text-lg text-gray-800">Third list item</li> </ul> </div> ); }
States and Responsiveness
Hover and Focus States
Tailwind provides state modifiers to conditionally apply custom list markers on states like hover
, focus
, etc. Here's how to apply custom list marker images:
export default function InteractiveList() { return ( <div className="w-screen h-screen flex items-center justify-center bg-gray-100"> <ul className="list-disc hover:list-image-[url('https://images.unsplash.com/photo-1517059224940-d4af9eec41b7?w=20')] pl-6 space-y-3"> <li className=" text-lg text-gray-900"> Interactive first item </li> <li className="text-lg text-gray-900"> Interactive second item </li> <li className="text-lg text-gray-900"> Interactive third item </li> </ul> </div> ); }
Breakpoint Modifiers
Responsive designs require list customizations that adapt to different screen sizes. Tailwind provides you with breakpoint modifiers(sm
, md
, etc.) to modify the list-style-image
property for various devices.
export default function ResponsiveList() { return ( <div className="w-screen h-screen flex items-center justify-center bg-gray-100"> <ul className="list-disc pl-8 md:list-image-[url('https://images.unsplash.com/photo-1517059224940-d4af9eec41b7?w=20')] space-y-4"> <li className="text-lg text-gray-700">Mobile-first bullet</li> <li className="text-lg text-gray-700">Adapts on medium screens</li> <li className="text-lg text-gray-700">Custom markers for wider displays</li> </ul> </div> ); }
Custom List Style Image
Extending the Theme
To fully integrate custom values, consider modifying Tailwind's theme in the tailwind.config.js
file. By extending the theme, you can register custom utilities for the list-style-image
property, making it easier to apply consistently across your project.
In the below example, image URL is saved as custom-marker in the theme file. Now, custom marker can be referenced as list-image-custom-marker
when needed:
import tailwindConfig from "./tailwind.config.js"; tailwind.config = tailwindConfig; export default function ThemeExtendedList() { return ( <div className="w-screen h-screen flex items-center justify-center bg-gray-100"> <ul className="list-image-custom-marker pl-6 space-y-4 text-gray-800"> <li>Styled with custom theme</li> <li>Using extended configuration</li> <li>Reusable across components</li> </ul> </div> ); }
Arbitrary Values for Flexibility
Use arbitrary values in Tailwind if you need to apply a unique marker that isn't predefined. This approach provides absolute flexibility for one-off designs.
Here, the image URL is passed directly using square brackets. Arbitrary values are especially useful in prototyping or when dealing with unique design specifications.
export default function ArbitraryStyledList() { return ( <div className="w-screen h-screen flex items-center justify-center bg-gray-100"> <ul className="list-image-[url('https://images.unsplash.com/photo-1517059224940-d4af9eec41b7?w=20')] pl-7 space-y-5 text-lg"> <li>On-the-fly marker styling</li> <li>Quick customization</li> <li>Bypassing predefined options</li> </ul> </div> ); }
Real World Examples
Product Features List
A modern product features list using custom image as list markers.
const FeaturesList = () => { const features = [ { title: "Advanced Analytics Dashboard", description: "Get deep insights into your business metrics with our interactive dashboard" }, { title: "Real-time Collaboration", description: "Work together seamlessly with your team members across different time zones" }, { title: "Automated Reporting", description: "Generate comprehensive reports with just one click" }, { title: "Custom Integrations", description: "Connect with your favorite tools and services effortlessly" }, { title: "Enterprise Security", description: "Bank-level encryption and advanced security features to protect your data" }, { title: "24/7 Support", description: "Get help whenever you need it with our round-the-clock support team" } ]; return ( <div className="max-w-4xl mx-auto p-8"> <ul className="space-y-6 list-none"> {features.map((feature, index) => ( <li key={index} className="pl-8 list-image-[url('https://images.unsplash.com/photo-1633409361618-c73427e4e206?w=20')]" > <div> <h4 className="text-lg font-semibold text-gray-900">{feature.title}</h4> <p className="text-gray-600 mt-1">{feature.description}</p> </div> </li> ))} </ul> </div> ); }; export default FeaturesList;
Subscription Benefits
A subscription benefits list of e-commerce platform with custom list image.
const BenefitsList = () => { const benefits = [ "Free shipping on all orders", "30-day money-back guarantee", "Lifetime warranty on products", "Premium customer support", "Exclusive member discounts", "Early access to new products" ]; return ( <div className="max-w-2xl mx-auto p-6 bg-white shadow-sm rounded-xl"> <ul className="space-y-3"> {benefits.map((benefit, index) => ( <li key={index} className="list-image-[url('https://images.unsplash.com/photo-1507925921958-8a62f3d1a50d?w=20')] ml-6 text-gray-700 p-3 border-b border-gray-100 last:border-0" > {benefit} </li> ))} </ul> </div> ); }; export default BenefitsList;
Job Requirements
A requirements list of a job listing with custom list image.
const RequirementsList = () => { const requirements = [ "5+ years of experience in web development", "Strong proficiency in React and TypeScript", "Experience with REST APIs and GraphQL", "Knowledge of CI/CD pipelines", "Excellent problem-solving skills", "Good communication and teamwork abilities" ]; return ( <div className="max-w-2xl mx-auto p-6"> <ul className="space-y-3 bg-blue-50 p-4 rounded-lg"> {requirements.map((requirement, index) => ( <li key={index} className="list-image-[url('https://images.unsplash.com/photo-1634896941598-b6b500a502a7?w=20')] ml-6 text-blue-900 p-2 bg-blue-100/50 rounded" > {requirement} </li> ))} </ul> </div> ); }; export default RequirementsList;
Installation Steps
A list of installation steps with custom list image.
const StepsList = () => { const steps = [ "Download and install the application", "Create your account and verify email", "Set up your profile information", "Configure your preferences", "Connect your social accounts", "Start using the platform" ]; return ( <div className="max-w-2xl mx-auto p-6 bg-gradient-to-br from-gray-50 to-white"> <ul className="space-y-4"> {steps.map((step, index) => ( <li key={index} className="list-image-[url('https://images.unsplash.com/photo-1614036417651-efe5912149d8?w=20')] ml-6 text-gray-700 pl-2" > <span className="font-medium text-gray-900">Step {index + 1}:</span> {step} </li> ))} </ul> </div> ); }; export default StepsList;
Documentation Menu Items
A list of doc menu items with custom list images.
const ResourcesList = () => { const resources = [ "Getting Started Guide", "API Documentation", "Video Tutorials", "Sample Projects", "Community Forums", "FAQs and Troubleshooting" ]; return ( <div className="max-w-2xl mx-auto p-6"> <ul className="space-y-3 bg-emerald-50 p-4 rounded-lg"> {resources.map((resource, index) => ( <li key={index} className="list-image-[url('https://images.unsplash.com/photo-1623282033815-40b05d96c903?w=20')] ml-6 text-emerald-800 bg-emerald-100/50 px-4 py-2 rounded-full" > {resource} </li> ))} </ul> </div> ); }; export default ResourcesList;
Customization Examples
Nature-themed Checklist
This example creates a nature-themed checklist using leaf images as bullet points.
import tailwindConfig from "./tailwind.config.js"; tailwind.config = tailwindConfig; export default function NatureChecklist() { return ( <div className="min-h-screen bg-green-50 p-8"> <div className="max-w-2xl mx-auto bg-white rounded-xl shadow-lg p-6"> <h2 className="text-2xl font-bold text-green-800 mb-4"> Garden Maintenance Tasks </h2> <ul className="list-image-leaf ml-6 space-y-3"> <li className="text-green-700 pl-2">Water the plants daily</li> <li className="text-green-700 pl-2">Trim the hedges</li> <li className="text-green-700 pl-2">Remove fallen leaves</li> <li className="text-green-700 pl-2">Check soil moisture</li> <li className="text-green-700 pl-2">Fertilize monthly</li> </ul> </div> </div> ) }
Tech Documentation Markers
This example uses custom arrow markers for a technical documentation list.
import tailwindConfig from "./tailwind.config.js"; tailwind.config = tailwindConfig; export default function TechDocumentation() { return ( <div className="min-h-screen bg-gray-900 p-8"> <div className="max-w-3xl mx-auto bg-gray-800 rounded-lg p-8"> <h2 className="text-3xl font-bold text-blue-400 mb-6"> Installation Steps </h2> <ul className="list-image-arrow ml-8 space-y-4"> <li className="text-gray-300 pl-4 border-b border-gray-700 pb-2"> Clone the repository from GitHub </li> <li className="text-gray-300 pl-4 border-b border-gray-700 pb-2"> Install dependencies using npm </li> <li className="text-gray-300 pl-4 border-b border-gray-700 pb-2"> Configure environment variables </li> <li className="text-gray-300 pl-4 border-b border-gray-700 pb-2"> Run database migrations </li> <li className="text-gray-300 pl-4"> Start the development server </li> </ul> </div> </div> ) }
Recipe Ingredients List
This example uses custom food icons for a recipe ingredients list.
import tailwindConfig from "./tailwind.config.js"; tailwind.config = tailwindConfig; export default function RecipeIngredients() { return ( <div className="min-h-screen bg-amber-50 p-8"> <div className="max-w-xl mx-auto bg-white rounded-2xl shadow-xl p-8"> <h2 className="text-3xl font-serif text-amber-800 mb-6"> Classic Pasta Recipe </h2> <div className="bg-amber-100 rounded-lg p-6"> <h3 className="text-xl font-semibold text-amber-900 mb-4"> Ingredients Needed: </h3> <ul className="list-image-ingredient ml-6 space-y-4"> <li className="text-amber-900 pl-4 font-medium"> 400g Fresh Pasta </li> <li className="text-amber-900 pl-4 font-medium"> 2 cloves of Garlic </li> <li className="text-amber-900 pl-4 font-medium"> 3 tbsp Olive Oil </li> <li className="text-amber-900 pl-4 font-medium"> Fresh Basil Leaves </li> <li className="text-amber-900 pl-4 font-medium"> Grated Parmesan </li> </ul> </div> </div> </div> ) }
Best Practices
Maintain Design Consistency
Extend the Tailwind's theme in tailwind.config.js
file to define reusable custom marker styles. For instance, you can create a branded bullet style and apply it uniformly across multiple components. This not only simplifies maintenance but also ensures your list designs remain visually aligned with the rest of your application.
By defining a custom listStyleImage
property like primary-icon
, you can reference it as a utility class (list-image-primary-icon
). This centralizes updates and ensures all instances of the style remain consistent in case of design changes. Always consider the reusability of your markers to avoid unnecessary redundancy.
Balance with Other Layout Properties
Ensuring that list-style-*
integrates well with other layout properties prevents unexpected design inconsistencies. For instance, combining list-inside
with leading-relaxed
creates a visually appealing list format by managing spacing between list items while keeping markers properly aligned with the text.
If working with flex or grid-based layouts, lists should be structured to complement surrounding elements. Additionally, use responsive padding (e.g., sm:pl-3
md:pl-6
, etc.) to ensure that list items remain properly spaced and visually distinct across different screen sizes.
Accessibility Considerations
Enhance Readability and Navigability
One of the key considerations when using list-style-image
is ensuring that it does not disrupt the logical reading order. By carefully selecting appropriate marker images and combining them with Tailwind’s list-inside
utility, you can maintain a structured and accessible layout.
The list-inside
ensures that list markers remain within the text flow rather than appearing outside the content block, which can be particularly helpful for screen reader users. Additionally, pairing this utility with appropriate spacing values to control the spacing between list items, preventing them from appearing cluttered or difficult to follow.
Focus on High Contrast
When using list style image, ensure high contrast between list markers and text to maintain readability. Low-contrast markers can blend into the background, making it difficult for users to distinguish individual list items.
One way to achieve high contrast is by choosing list images with distinct colors that stand out against the background. If your list items use a light background, opt for dark or bold-colored markers, and vice versa. Tailwind’s utility classes like invert
, brightness-*
, and contrast-*
can be applied to refine the appearance of custom list markers. These adjustments ensure that markers maintain sufficient visibility even under different UI themes, including dark mode.