0
\$\begingroup\$

I'm using React and Tailwind to generate cards like the example below. I was hoping to get feedback on the CSS rules I used, the order of the Tailwind classnames, and the HTML structure. I'm using flex in several places because I'm used to it, but isn't there a better alternative "best practices"-wise?

Example card, Mega Sceptile:

Example card for Mega Sceptile

In Icon, the pokémon type icons are wrapped in a div with the matching colored background. I used flex to make sure the icon is fully centered. Note that Image is an element provided by Next.js and requires passing weight and height, so I approximated height: 60% with 30 * 0.6.

In Card I justify-around the text and icon divs to keep them off the sides, while using flex basis-20 to make sure the icons are closer to the edge than the text, and that the text takes most of the space.

import Image from 'next/image';
import React from 'react';

import { Pokemon } from '@/types/pokemon.ts';

function Icon({ type }: { type: string }) {
  return (
    // flex used to center the type icon inside the colored div
    <div className={`${type} h-[30px] w-[30px] flex rounded-full transition-all hover:saturate-200 hover:scale-110`}>
      <Image
        src={`type-icons/${type}.svg`}
        alt={type}
        title={type}
        width={30 * 0.6}
        height={30 * 0.6}
        className='m-[20%]'
      />
    </div>
  );
}

export default function Card({ pokemon }: { pokemon: Pokemon }) {
  const { id, name, sprite, type1, type2 } = pokemon;

  // names and extensions (like "mega") are provided in lower case
  // and separated by hyphens
  const [n, ...extensions] = name.split('-');

  return (
    <div className='h-[23vh] p-1 grid bg-white border-gray-200 border-[1px] hover:bg-gray-200 hover:cursor-pointer'>
      <div className='flex justify-around '>
        <div className='basis-20'>
          <p className='text-gray-600'>{id}</p>
          {/* Capitalize first letter of name */}
          <p className='text-gray-500'>{n?.replace(/\b\w/, c => c.toUpperCase())}</p>
          <p className='text-gray-300 text-xs'>{extensions.join(' ')}</p>
        </div>
        <div className='flex flex-col justify-between'>
          <Icon type={type1} />
          {type2 && <Icon type={type2} />}
        </div>
      </div>
      <img src={sprite} alt={name} className='m-auto' />
    </div>
  );
}

\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.