Search code examples
cssvue.jsflexboxvuetify.jsvuetifyjs3

How can I make v-col turn scrollable?


I'm trying to achieve the following layout.

  • The grey container shall spread over the whole viewport but shall not be larger
  • The green v-row shall fill the grey container
  • v-col 1 shall fill the available space, a scrollbar shall be added if necessary
  • v-col 2 shall fill the available space and shrink if necessary
  • v-col 3 shall always be on the bottom and only take the necessary space

enter image description here

So far I have the following. The problem is that '1' doesn't turn scrollable but instead pushes '2' and '3' out of the viewport. What am I doing wrong?

Bonus question: Is there a better way to have the container fill the viewport? 100% doesn't work for me for some reason.

Even more bonus: Would it be easier to achieve this with only regular divs?

<template>
  <v-app>
    <v-container class="ma-0 pa-0 d-flex full-height">
      <v-row no-gutters class="d-flex flex-column flex-nowrap flex-1-0-100">
        <!-- column 1 -->
        <v-col class="overflow-y-auto flex-1-0">
          <v-list :items="dummy"></v-list>
        </v-col>

        <!-- column 2 -->
        <v-col class="d-flex justify-center flex-1-1-100">
          <v-btn color="primary">+</v-btn>
        </v-col>

        <!-- column 3 -->
        <v-col class="d-flex justify-center flex-0-1">
          <v-btn color="secondary">Schließen</v-btn>
        </v-col>
      </v-row>
    </v-container>
  </v-app>
</template>

<script setup>
  const length = 10 // Adjust for smaller/larger array
  const dummy = [...Array(length).keys()]
</script>

<style scoped>
  .full-height {
    height: calc(100vh - 37px);
  }
</style>

Solution

  • From what I understand, you want to distribute unused space equally between column 1 and 2, but column 1 should take up as much space as possible, but not more than available.

    Then there are two issues:

    • column 1 can grow and not shrink (flex-1-0), but you want it to not take up more space than what is left from the other columns, so it should shrink if there isn't enough space available, so it should be flex-1-1
    • flex-basis of column 2 is set to 100% (flex-1-1-100), but it should only take up space left by column 1, so it should be flex-1-1

    Here is a playground


    To me, it is confusing to use v-row and v-col if your layout is just a flex-column. Seems easier to just use divs in this case, particularly since v-col has its own flex rules that might get in your way. Here is a playground using divs.