1

This is Vuetify 3. I'm not using any custom CSS, just Vuetify layout classes. I'm creating a MonthPicker component.

Here is the final output:

enter image description here

This is a simple v-menu with a v-card in it. The card has two columns, for month and year selection. The left column is further divided into a 4x3 layout for 12 months (but that is not relevant to the problem at hand).

Here are the rules:

  • I don't want to specify height on any element except the month buttons. The buttons should dictate the height of the left column, while the right column should take as much height as the left column. The card itself should take as much height as needed by the columns, no more.
  • If second column (years) content is taller than the available space, an overflow scrollbar should appear as shown in the image.

The only problem I have here is that the right column height is specified explicitly in this setup (like height="197") which I don't want. As soon as I remove the height attribute, the column expands to take as much space as available in the viewport.

I have tried many approaches including flex, css grid and absolute position, to no avail. Absolute position kind of works, but the right column starts overlapping the left column.

Is there a way for the second column to take as much height as dictated by the first column?

Here is my template layout (I have removed unnecessary stuff):

  <v-card width="500">
    <v-container>
      <v-row no-gutters>
        <v-col class="pa-1">
          <v-sheet>
            <v-row no-gutters>
              <v-col cols="3" v-for="c in 12" :key="c">
                <v-btn height="60">
                  {{ months[c - 1] }}
                </v-btn>
              </v-col>
            </v-row>
          </v-sheet>
        </v-col>

        <v-col cols="auto">
          <v-sheet>
            <v-row no-gutters>
              <v-col>
                <v-list lines="one" height="197">
                  <v-list-item-group>
                    <div v-for="n in 100" :key="n">
                      {{ n + 2000 }}
                    </div>
                  </v-list-item-group>
                </v-list>
              </v-col>
            </v-row>
          </v-sheet>
        </v-col>
      </v-row>
    </v-container>
  </v-card>
dotNET
  • 33,414
  • 24
  • 162
  • 251

1 Answers1

1

You can use the height:0;min-height:100% trick, , where you set the height of the inner container to 0, so it does not contribute to the height of the outer container, and restore the inner height by setting a min-height:

.year-container{
  height: 0;
  min-height: 100%;
  overflow: auto;
}

You can do this on the sheet. Have a look at the snippet:

const { createApp, ref } = Vue;
const { createVuetify } = Vuetify
const vuetify = createVuetify()
const app = {
  setup(){
    
    return {
      months: ref(['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec',])
    }
  }

}
createApp(app).use(vuetify).mount('#app')
.year-container{
  height: 0;
  min-height: 100%;
  overflow: auto;
  width: 50px;
}
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/vuetify@3/dist/vuetify.min.css" />
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">
<div id="app">
  <v-app>
    <v-main>
      <v-card width="500">
        <v-container>
          <v-row no-gutters>
            <v-col class="pa-1">
              <v-sheet>
                <v-row dense>
                  <v-col cols="3" v-for="c in 12" :key="c">
                    <v-btn height="60" color="orange">
                      {{ months[c - 1] }}
                    </v-btn>
                  </v-col>
                </v-row>
              </v-sheet>
            </v-col>

            <v-col cols="auto">
              <v-sheet class="year-container">
                <v-row no-gutters>
                  <v-col>
                    <v-list lines="one">
                      <v-list-item-group>
                        <div v-for="n in 100" :key="n">
                          {{ n + 2000 }}
                        </div>
                      </v-list-item-group>
                    </v-list>
                  </v-col>
                </v-row>
              </v-sheet>
            </v-col>
          </v-row>
        </v-container>
      </v-card>
    </v-main>
  </v-app>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@3/dist/vuetify.min.js"></script>
Moritz Ringler
  • 9,772
  • 9
  • 21
  • 34