tailwind-csstailwind-3

What am I doing wrong in my Tailwind timeline where my even items are not displaying over the line correctly?


Playing around with building a timeline in Tailwind CSS version 3.4.1 I'm wondering what I am doing wrong when it comes to my secondary icons not presenting over the line correctly.

Code:

import { ClipboardCheck, MessageSquare, Wrench, Car } from "lucide-react";

export default function TimelineExperiement() {
  const timeline = [
    {
      icon: <MessageSquare className="h-10 w-10 text-red-600" />,
      title: "Monday",
      description:
        "Bacon ipsum dolor amet shankle bresaola venison corned beef frankfurter short ribs pastrami pancetta porchetta tri-tip sausage fatback pork loin rump.",
    },
    {
      icon: <ClipboardCheck className="h-10 w-10 text-red-600" />,
      title: "Tuesday",
      description:
        "Bacon ipsum dolor amet shankle bresaola venison corned beef frankfurter short ribs pastrami pancetta porchetta tri-tip sausage fatback pork loin rump.",
    },
    {
      icon: <Wrench className="h-10 w-10 text-red-600" />,
      title: "Wednesday",
      description:
        "Bacon ipsum dolor amet shankle bresaola venison corned beef frankfurter short ribs pastrami pancetta porchetta tri-tip sausage fatback pork loin rump.",
    },
    {
      icon: <Car className="h-10 w-10 text-red-600" />,
      title: "Thursday",
      description:
        "Bacon ipsum dolor amet shankle bresaola venison corned beef frankfurter short ribs pastrami pancetta porchetta tri-tip sausage fatback pork loin rump.",
    },
  ];

  return (
    <section id="process" className="py-16 bg-gray-50">
      <div className="container mx-auto px-4">
        <div className="text-center mb-12">
          <h2 className="text-3xl font-bold text-gray-800 mb-4">Timeline</h2>
          <p className="text-gray-600 max-w-2xl mx-auto">
            Landjaeger alcatra shankle, buffalo cupim kielbasa short ribs
            burgdoggen.
          </p>
        </div>

        <div className="relative">
          <div className="hidden md:block absolute left-1/2 top-0 bottom-0 w-1 bg-red-200 transform -translate-x-1/2" />
          <div className="space-y-12 relative">
            {timeline.map((tl, index) => (
              <div
                key={index}
                className="flex flex-col md:flex-row items-center"
              >
                <div
                  className={`md:w-1/2 ${
                    index % 2 === 0
                      ? "md:pr-12 md:text-right"
                      : "md:order-2 md:pl-12 "
                  }`}
                >
                  <h3 className="text-xl font-bold text-gray-800 mb-2">
                    {tl.title}
                  </h3>
                  <p className="text-gray-600">{tl.description}</p>
                </div>

                <div
                  className={`my-4 md:my-0 z-10 bg-white rounded-full p-4 shadow-md`}
                >
                  {tl.icon}
                </div>

                <div
                  className={`md:w-1/2 ${
                    index % 2 === 0 ? "md:order-2" : "md:text-right"
                  }`}
                />
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

How can I on even items get the icon over the solid lines?


Solution

  • As an alternative solution, swapping the md:flex-row and md:flex-row-reverse classes could be perfect instead of adjusting the order.

    const { useState, useEffect } = React;
    
    function TimelineExperiement() {
      const timeline = [
        {
          icon: <div className="h-10 w-10 text-red-600" />,
          title: "Monday",
          description:
            "Bacon ipsum dolor amet shankle bresaola venison corned beef frankfurter short ribs pastrami pancetta porchetta tri-tip sausage fatback pork loin rump.",
        },
        {
          icon: <div className="h-10 w-10 text-red-600" />,
          title: "Tuesday",
          description:
            "Bacon ipsum dolor amet shankle bresaola venison corned beef frankfurter short ribs pastrami pancetta porchetta tri-tip sausage fatback pork loin rump.",
        },
        {
          icon: <div className="h-10 w-10 text-red-600" />,
          title: "Wednesday",
          description:
            "Bacon ipsum dolor amet shankle bresaola venison corned beef frankfurter short ribs pastrami pancetta porchetta tri-tip sausage fatback pork loin rump.",
        },
        {
          icon: <div className="h-10 w-10 text-red-600" />,
          title: "Thursday",
          description:
            "Bacon ipsum dolor amet shankle bresaola venison corned beef frankfurter short ribs pastrami pancetta porchetta tri-tip sausage fatback pork loin rump.",
        },
      ];
    
      return (
        <section id="process" className="py-16 bg-gray-50">
          <div className="container mx-auto px-4">
            <div className="text-center mb-12">
              <h2 className="text-3xl font-bold text-gray-800 mb-4">Timeline</h2>
              <p className="text-gray-600 max-w-2xl mx-auto">
                Landjaeger alcatra shankle, buffalo cupim kielbasa short ribs
                burgdoggen.
              </p>
            </div>
    
            <div className="relative">
              <div className="hidden md:block absolute left-1/2 top-0 bottom-0 w-1 bg-red-200 transform -translate-x-1/2" />
              <div className="space-y-12 relative">
                {timeline.map((tl, index) => (
                  <div
                    key={index}
                    className={`flex flex-col items-center ${
                        /* HERE */
                        index % 2 === 0
                          ? "md:flex-row"
                          : "md:flex-row-reverse"
                      }`}
                  >
                    {/* TEXT */}
                    <div
                      className={`md:w-1/2 ${
                        index % 2 === 0
                          ? "md:pr-12 md:text-right"
                          : "md:pl-12"
                      }`}
                    >
                      <h3 className="text-xl font-bold text-gray-800 mb-2">
                        {tl.title}
                      </h3>
                      <p className="text-gray-600">{tl.description}</p>
                    </div>
    
                    {/* ICON */}
                    <div
                      className={`my-4 md:my-0 z-10 bg-white rounded-full p-4 shadow-md`}
                    >
                      {tl.icon}
                    </div>
    
                    {/* EMPTY */}
                    <div
                      className={`md:w-1/2 ${
                        index % 2 === 0 ? "" : "md:text-right"
                      }`}
                    />
                  </div>
                ))}
              </div>
            </div>
          </div>
        </section>
      );
    }
    
    ReactDOM.createRoot(document.getElementById("root")).render(<TimelineExperiement />);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js"></script>
    <script src="https://cdn.tailwindcss.com"></script>
    
    <div id="root"></div>