Home > Software engineering >  Is there anyway to target nth child in tailwind-css v3?
Is there anyway to target nth child in tailwind-css v3?

Time:11-08

I have a total of 10 items and I am mapping through them to render each one. I want least opacity for last element and highest for first element. I am aware of :first and :last in tailwind-css, but I was wondering if there is way so that I can target lets say my 8th or 9th in tailwind-css

here is my return statement from a component:

    {[0,1,2,3,4,5,6,7,8,9].map((item) => (
                            <section
                                key={item}
                                className='last:opacity-20 flex justify-between items-center text-slate-600 bg-white shadow-sm p-5 rounded-xl my-4 cursor-pointer dark:bg-black dark:text-slate-400'
                            >
                                <div className='flex gap-3 items-center'>
                                    <div className='rounded-full w-8 h-8 bg-slate-200'></div>
                                    <p className='w-44 h-4 bg-slate-100'></p>
                                </div>
                                <p className='w-16 h-4 bg-slate-100'></p>
                            </section>
                        ))}

I want to decrease opacity going downwards i.e, from first item to last item.

CodePudding user response:

Targeting nth-child can be easy using Tailwind v3.2 matchVariant

// tailwind.config.js
let plugin = require("tailwindcss/plugin");

module.exports = {
  plugins: [
    plugin(function ({ matchVariant, theme }) {
      matchVariant(
        'nth',
        (value) => {
          return `&:nth-child(${value})`;
        },
        {
          values: {
            DEFAULT: 'n', // Default value for `nth:`
            '2n': '2n', // `nth-2n:utility` will generate `:nth-child(2n)` CSS selector
            '3n': '3n',
            '4n': '4n',
            '5n': '5n',
            //... so on if you need
          },
        }
      );
    }),
  ],
}

Usage - every 2n element will be red, 1st, 6th, 11th, 5n 1 - green, every fifth - blue (it will overlap but it is just an example how to use it from config or arbitrary variants)

<ul >
  
  <li >1</li>
  <li >2</li>
  <li >3</li>
  <li >4</li>
  <li >5</li>
  <li >6</li>

</ul>

DEMO

For versions bellow 3.2 you'll need to add variant addVariant for every nth-child selector

CodePudding user response:

This following solution may not use nth-child but does give the needed result: list items will have reduced opacity one by another.

 {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((item) => {
        // Generate class name
        // Need to config Tailwind as shown later for this to work
        const opacity = `opacity-${(10 - item) * 10}`;

        // Changed to bg-black here so result is more visible
        return (
          <section
            key={item}
            className={`${opacity} flex justify-between items-center text-slate-600 bg-black shadow-sm p-5 rounded-xl my-4 cursor-pointer dark:bg-black dark:text-slate-400`}
          >
            <div className="flex gap-3 items-center">
              <div className="rounded-full w-8 h-8 bg-slate-200"></div>
              <p className="w-44 h-4 bg-slate-100"></p>
            </div>
            <p className="w-16 h-4 bg-slate-100"></p>
          </section>
        );
      })}

But before this can be rendered, in order for Tailwind to generate the class names needed, the following config need to be added to tailwind.config.cjs:

const opacitySafeList = [];

for (i = 1; i < 11; i  ) {
  opacitySafeList.push(`opacity-${i * 10}`);
}

module.exports = {
  content: ["...content of the project"],

// Tell Tailwind to generate these class names which does not exist in content files
  safelist: opacitySafeList,

  theme: {
    extend: {},
  },
  plugins: [],
};

This feature (safe list) is considered last resort by Tailwind, but this question seem to be a good use case for it.

  • Related