<main id="calendar">
  <div>S</div>
  <div>M</div>
  <div>T</div>
  <div>W</div>
  <div>T</div>
  <div>F</div>
  <div>S</div>
  
  <div v-for="(day, index) in days" :style="{ gridColumn: column(index) }" :class="{ today: today(day) }">
    {{ day.format('D') }}
  </div>
</main>
html, body{
  height: 100%;
  width: 100%;
}

body{
  align-items: center;
  background: #768768;
  box-sizing: border-box;
  display: flex;
  font: calc(2vh) "Helvetica", sans-serif;
  justify-content: center;
  padding: 2em;
}

#calendar{
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  max-width: 1024px;
  width: 100%;
}

#calendar > *{
  align-items: center;
  display: flex;
  justify-content: center;
}

#calendar > *::before {
  content: "";
  display: inline-block;
  height: 0;
  padding-bottom: 100%;
  width: 1px;
}

#calendar > *.today{
  color: white;
  border: 0.1em solid white;
  border-radius: 100%;
}
const app = new Vue({
  el: '#calendar',
  data() {
    return {
      days: []  
    }
  },
  methods: {
    column(index) {
      if (index == 0) {
        return this.days[0].day() + 1
      }
    },
    today(day) {
      return moment().isSame(day, 'day')
    }
  },
  mounted() {
    let monthDate = moment().startOf('month')
    
    this.days = [...Array(monthDate.daysInMonth())].map((_, i) => monthDate.clone().add(i, 'day'))
  }
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.22/vue.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js