Search code examples
formsfrontendtailwind-cssiconsposition

Positioning an Icon in a Registration Form in Tailwind


I'm building a registration form and I'm having trouble positioning the eye icon. Initially, the icon is positioned correctly, but when an error message is displayed, it gets misaligned.

Here are some screenshots showing the issue, along with the code I'm using.

enter image description here

enter image description here

Additionally, I can't figure out how to make the error message icon larger. For longer error messages, the icon becomes too small.

enter image description here

This is my code:

                    <div className="mt-6">
                        <label htmlFor="password" className="block text-sm font-normal text-gray-700">
                            Contraseña
                        </label>
                        <div className="mt-1 relative">
                            <input
                                id="password"
                                name="password"
                                type={showPassword ? 'text' : 'password'}
                                autoComplete="current-password"
                                placeholder="Contraseña"
                                required
                                value={password}
                                onChange={(e) => setPassword(e.target.value)}
                                onBlur={() => handleBlur('password')}
                                className="block w-full appearance-none placeholder:text-xs rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-neutral-950 focus:outline-none sm:text-sm"
                            />
                            <span
                                onClick={togglePasswordVisibility}
                                className="absolute inset-y-0 right-0 pr-3 flex items-center cursor-pointer justify-center"
                            >
                                {showPassword ? <VscEyeClosed /> : <VscEye />}
                            </span>

                            {passwordError && (
                                <p className="mt-2 text-xs text-red-600 flex items-center">
                                    <TiWarning className="mr-1" /> {passwordError}
                                </p>
                            )}

                        </div>
                    </div>

I'm using Tailwind CSS, and to be honest, I don't have much experience with frontend development. It feels like a nightmare for a backend developer! Could someone help me fix these issues?


Solution

  • For positioning the eye icon:
    I replaced inset-y-0 with top-3 to ensure consistent alignment, as inset-y-0 adjusts dynamically based on the height of the input. Using top-3 fixes the position relative to the top of the input field.

    <span
      onClick={togglePasswordVisibility}
      className="absolute top-3 right-0 pr-3 flex items-center cursor-pointer justify-center"
    >
      {showPassword ? <VscEyeClosed /> : <VscEye />}
    </span>
    

    For the warning icon size issue:
    I added flex-shrink-0 to prevent the icon from shrinking when the error message wraps to multiple lines. Additionally, I set explicit height (h-4) and width (w-4) to maintain consistent size.

    <TiWarning className="mr-1 flex-shrink-0 h-4 w-4 text-lg" />
    

    Here’s the full updated code:

    <div className="mt-6">
      <label
        htmlFor="password"
        className="block text-sm font-normal text-gray-700"
      >
        Contraseña
      </label>
      <div className="mt-1 relative">
        <input
          id="password"
          name="password"
          type={showPassword ? "text" : "password"}
          autoComplete="current-password"
          placeholder="Contraseña"
          required
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          onBlur={() => handleBlur("password")}
          className="block w-full appearance-none placeholder:text-xs rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-neutral-950 focus:outline-none sm:text-sm"
        />
        <span
          onClick={togglePasswordVisibility}
          className="absolute top-3 right-0 pr-3 flex items-center cursor-pointer justify-center"
        >
          {showPassword ? <VscEyeClosed /> : <VscEye />}
        </span>
    
        {passwordError && (
          <p className="mt-2 text-xs text-red-600 flex items-center">
            <TiWarning className="mr-1 flex-shrink-0 h-4 w-4 text-lg" />
            {passwordError}
          </p>
        )}
      </div>
    </div>
    

    These changes ensure the components remain properly aligned and visually consistent regardless of input height or error message length.