0

I made calendar that displays every day in each month for all 12 months. What would be the proper way to style these day blocks in order to get the days to wrap at the end of of 7 days?. As it is now, they don't flex to the end, but the bigger problem is I only want 7 dayblocks to show in each row.

Should I use CSS or is the real problem my logic? (basically want to look like a actually calendar). Here is an image of what it looks like for me currently: calendar

<script lang="ts">
    const weekNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thurs', 'Fri', 'Sat'];
    const months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];

    let daysInMonth: Array<string> = [];
    let dayNumberArray: Array<number> = [];
    let days: Array<Date> = [];

    const getDaysInMonth = (month: number, year: number) => {
        //create a date...
        let date = new Date(year, month);
        //loop through months...
        while (date.getMonth() === month) {
            days.push(new Date(date));
            date.setDate(date.getDate() + 1);
        }
        for (let i = 0; i < daysInMonth.length; i++) {
            dayNumberArray.push(i);
        }
    };

    //for each month...
    months.forEach((m) => {
        //pass the month and year...
        getDaysInMonth(m - 1, 2023);
    });

    const getDaysInYear = (year: number) => {
        daysInYear = checkLeapYear(year) ? 366 : 365;
    };

    const checkLeapYear = (year: number) => {
        return year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0);
    };
</script>

<main>
    <section class="cal">
        <div class="cal-header">
            <h1>Calendar</h1>
        </div>
        <div class="cal-week">
            {#each weekNames as week}
                <div class="cal-weekday">
                    {week}
                </div>
            {/each}
        </div>
        <div class="cal-month">
            {#each days as day}
                {#if day}
                    <div class="cal-day">
                        <div class="cal-num">
                            {day.getDate()}
                        </div>
                    </div>
                {/if}
            {/each}
        </div>
    </section>
</main>

<style>
    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    .cal {
        width: 100%;
        height: 100%;
        font-family: 'Poppins';
        overflow-y: scroll;
        border: 1px solid black;
    }
    .cal-header {
        display: flex;
        justify-content: center;
        border: 1px solid black;
    }
    .cal-week {
        display: flex;
        border: 1px solid black;
        background-color: rgb(146, 216, 183);
    }
    .cal-weekday {
        display: flex;
        justify-content: center;
        width: 100%;
    }
    .cal-month {
        display: flex;
        flex-wrap: wrap;
        width: 100%;
        height: auto;
        border: 1px solid black;
    }
    .cal-day {
        font-size: 28px;
        font-weight: bold;
        border-radius: 8px;
        min-width: 100px;
        line-height: 100px;
        height: 100px;
        text-align: center;
        margin: 5px;
        border: 1px solid black;
    }
    .cal-day:hover {
        background-color: rgb(230, 229, 229);
    }
    .cal-num {
        font-size: 1.5rem;
        padding: 0.15rem;
    }
</style>
lache
  • 608
  • 2
  • 12
  • 29
  • 1
    You can use `flex-wrap: wrap;` for a flex container (i.e. `.cal-week` in your case), and `flex-basis` property (or `flex` shorthand) for the flex items (i.e. `.cal-day` in your case) with 1/7 fraction. Or, you could easily use a `table` layout instead for a more straightforward implementation. – Bumhan Yu Mar 24 '23 at 04:17
  • 1
    Or also consider `grid` instead. – Bumhan Yu Mar 24 '23 at 04:45
  • I think the real solution might be to loop and display each week and not every day? I am trying the table thing too but no luck – lache Mar 24 '23 at 13:00
  • found this might be a style answer, but still not sure if 'right' way. https://stackoverflow.com/questions/29546550/flexbox-4-items-per-row – lache Mar 24 '23 at 14:02
  • 1
    Looping and rendering logic has very little to do with this. It all comes down to the actual DOM nodes (or HTML markups) that result from your JavaScript and their styling in CSS. The simplest way to do this might be using `display: grid;` and keep the number of columns to `7`. I’d suggest you look into the HTML/CSS fundamentals. – Bumhan Yu Mar 24 '23 at 20:29
  • thanks! i tried changing the logic but I like getting all the days as a 'list' so I went with the flex in the link for now, but ill explore the grid too! – lache Mar 24 '23 at 23:31

1 Answers1

0

Use display: grid; with the 7-column grid layout

If you have a continuous list of numbers as dates to render as days of the week within calendar, table or grid would be your two best, easiest bets.

In the snippet below, I used your existing HTML and CSS markup and tweaked with display: grid instead of flex;

Main takeaways include:

  • Use display: grid instead of flex
  • Define 7-column grid — e.g. grid-template-columns: repeat(7, 1fr)
  • (optional) add grid-gap to add space between cells

You could achieve the same effect with flex as well, but grid would give you the most straightforward structure.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.cal {
  width: 100%;
  height: 100%;
  font-family: 'Poppins';
  overflow-y: scroll;
  border: 1px solid black;
}

.cal-header {
  display: flex;
  justify-content: center;
  border: 1px solid black;
}

.cal-week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  border: 1px solid black;
  background-color: rgb(146, 216, 183);
}

.cal-weekday {
  display: flex;
  justify-content: center;
  width: 100%;
}

.cal-month {
  display: grid;
  grid-template-columns: repeat(7, 1fr);  
  width: 100%;
  height: auto;
  border: 1px solid black;
}

.cal-day {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  font-weight: bold;
  border-radius: 8px;
  height: 100px;
  text-align: center;
  border: 1px solid black;
}

.cal-day:hover {
  background-color: rgb(230, 229, 229);
}

.cal-num {
  font-size: 1.5rem;
  padding: 0.15rem;
}
<main>
  <section class="cal">
    <div class="cal-header">
      <h1>Calendar</h1>
    </div>
    <div class="cal-week">
      <div class="cal-weekday">
        Sun
      </div>
      <div class="cal-weekday">
        Mon
      </div>
      <div class="cal-weekday">
        Tue
      </div>
      <div class="cal-weekday">
        Wed
      </div>
      <div class="cal-weekday">
        Thur
      </div>
      <div class="cal-weekday">
        Fri
      </div>
      <div class="cal-weekday">
        Sat
      </div>
    </div>
    <div class="cal-month">
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
      <div class="cal-day">
        <div class="cal-num">
          1
        </div>
      </div>
    </div>
  </section>
</main>
Bumhan Yu
  • 2,078
  • 1
  • 10
  • 20