skip to Main Content

I built myself a little weekly forecast app for an exercise and I’m using TailwindCSS. On medium sized screens and larger, I have the layout pretty much how I’d like it (still tweaking). There are two columns, day-time weather data on the left, night-time weather data on the right. Each row is one day. Vertical scrolling should be fine for desktop.

On mobile screens, I decided I’d like to have two rows, the top being day-time data, the bottom being night-time data. I think it would work well if you could horizontally scroll and have each day snap to the center and overflow the screen to the right or left. My mental image is like a window just a smidge smaller than the width of the screen and each day of weather slides into view from the left or right.

The problem I’m having is something in my CSS is causing the divs (days) to overlap each other horizontally on mobile.

Here is the related code (React and TailwindCSS):

<div className="w-full grid grid-cols-7 grid-rows-2 grid-flow-col overflow-x-clip snap-x md:grid-cols-2 md:grid-flow-row md:grid-rows-7 gap-4">
  {forecast.map(period => (
  <div className="border w-[325px] h-[200px] justify-self-center rounded-2xl p-2 snap-center" key={`${period.number}-outer-div`}>
    <div className="">
      {period.name}
    </div>
    <div className="flex w-full max-h-[100px]" key={`${period.number}-inner-div`}>
      <div className="">
        <Image className="max-h-[100px] max-w-[100px]" src={period.icon} key={`${period.number}-icon`} width={100} height={100} alt="Forecast Icon" />
      </div>
      <div className="w-full px-2">
        <ul key={`${period.number}-list`}>
          <li key={`${period.number}-temp`}>Temp: {period.temperature}&deg;{period.temperatureUnit}</li>
          <li key={`${period.number}-dew`}>Dewpoint: {period.dewpoint.value?.toFixed(2)}&deg;{period.dewpoint.unitCode.replace('wmoUnit:deg', '')}</li>
          <li key={`${period.number}-hum`}>Humidity: {period.relativeHumidity.value}%</li>
          <li key={`${period.number}-wind`}>Wind: {period.windSpeed} {period.windDirection}</li>
        </ul>
      </div>
    </div>
    <div className="">
      <p className="weather" key={`${period.number}-detail`}>{period.detailedForecast}</p>
    </div>
  </div>
  ))}
</div>

Here’s the current Desktop version

Here’s the current Mobile version

2

Answers


  1. Chosen as BEST ANSWER

    Thank you @Iniubon Obonguko you pointed me in enough of direction that I resolved it mostly. I had to stick with 'grid-flow-col' because I wanted the columns filled first (in mobile). I removed the 'grid-cols-7' and that allowed it to stretch out for some reason. Using 'w-full' somehow kept each column smaller, so I stuck with 'w-[375px]'.

    The only thing that could make the end result a little more eye-pleasing to me is having the first and last day centered on the screen, so some kind of buffer on the left of the first "day" and right of the last "day" would be perfect. I think I can figure something out.

    I cannot thank you enough @Iniubong Obonguko!

    Final code (so far):

    <div className="w-full grid grid-flow-col grid-rows-2 overflow-auto snap-x md:grid-flow-row md:grid-cols-2 md:grid-rows-7 gap-4">
      {forecast.map(period => (
        <div className="border w-[325px] h-[200px] md:justify-self-center rounded-2xl p-2 snap-center" key={`${period.number}-outer-div`}>
          <div className="">
            {period.name}
          </div>
          <div className="flex w-full max-h-[100px]" key={`${period.number}-inner-div`}>
          <div className="">
            <Image className="max-h-[100px] max-w-[100px]" src={period.icon} key={`${period.number}-icon`} width={100} height={100} alt="Forecast Icon" />
          </div>
          <div className="w-full px-2">
            <ul key={`${period.number}-list`}>
              <li key={`${period.number}-temp`}>Temp: {period.temperature}&deg;{period.temperatureUnit}</li>
              <li key={`${period.number}-dew`}>Dewpoint: {period.dewpoint.value?.toFixed(2)}&deg;{period.dewpoint.unitCode.replace('wmoUnit:deg', '')}</li>
              <li key={`${period.number}-hum`}>Humidity: {period.relativeHumidity.value}%</li>
              <li key={`${period.number}-wind`}>Wind: {period.windSpeed} {period.windDirection}</li>
            </ul>
          </div>
        </div>
        <div className="">
          <p className="weather" key={`${period.number}-detail`}>{period.detailedForecast}</p>
        </div>
      </div>
      ))}
    </div>
    

    The first "day" showing (first 24 hours):

    Any "middle" "day" showing:

    The last "day" showing (last 24 hours)


  2. First, reduce the number of elements in the grid on the mobile screen to 1 or 2, so set grid-cols-1 and change the grid-flow-col to grid-flow-row, or feel free to remove it entirely as row is the default value.

    According to MDN, "Items are placed by filling each column in turn, adding new columns as necessary." Which is why all the elements are overlapping in that manner. Items are placed into columns before moving to the next row.

    Finally, remove the fixed width on the card items. So change w-[325px] to w-full

    Here’s the full changes.

          <div className="w-full grid grid-cols-2 grid-rows-2 grid-flow-row overflow-x-clip snap-x md:grid-cols-2 md:grid-flow-row md:grid-rows-7 gap-4">
            {forecast.map((period) => (
              <div
                className="border w-full h-[200px] justify-self-center rounded-2xl p-2 snap-center"
                key={`${period.number}-outer-div`}
              >
                <div className="">{period.name}</div>
                <div
                  className="flex w-full max-h-[100px]"
                  key={`${period.number}-inner-div`}
                >
                  <div className="">
                    <Image
                      className="max-h-[100px] max-w-[100px]"
                      src={period.icon}
                      key={`${period.number}-icon`}
                      width={100}
                      height={100}
                      alt="Forecast Icon"
                    />
                  </div>
                  <div className="w-full px-2">
                    <ul key={`${period.number}-list`}>
                      <li key={`${period.number}-temp`}>
                        Temp: {period.temperature}&deg;{period.temperatureUnit}
                      </li>
                      <li key={`${period.number}-dew`}>
                        Dewpoint: {period.dewpoint.value?.toFixed(2)}&deg;
                        {period.dewpoint.unitCode.replace("wmoUnit:deg", "")}
                      </li>
                      <li key={`${period.number}-hum`}>
                        Humidity: {period.relativeHumidity.value}%
                      </li>
                      <li key={`${period.number}-wind`}>
                        Wind: {period.windSpeed} {period.windDirection}
                      </li>
                    </ul>
                  </div>
                </div>
                <div className="">
                  <p className="weather" key={`${period.number}-detail`}>
                    {period.detailedForecast}
                  </p>
                </div>
              </div>
            ))}
          </div>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search