Reputation: 385
I have a page with 6 or more v-card.
Is there a way to fit them like a puzzle? I would like to remove white space between small v-card on first and second line.
Now is like this:
Upvotes: 3
Views: 4715
Reputation: 378
I found a simple solution (in this blog) with anything else than CSS. The same blog gives more examples of different grids and also some examples to make things prettier with JS.
The easiest way is to define a grid of columns the way you want. For example, I want on my proyect a 3 column grid about 400px
each.
So we define a class masonry-with-columns
, we put all the properties we want (margin, padding, column-gap, row-gap, etc)
.masonry-with-columns {
columns: 3 400px;
column-gap: 10px;
max-width: 100%;
}
Each child must have 2 properties
.masonry-with-columns div {
display: inline-block;
width: 100%;
}
inline-block
: prevents objects from being cutwidth: 100%
: When you do not put this property, at the time of loading it is displayed with a reduced width and then it expands, to avoid that, we must define a width<template>
<v-container
fill-height
fluid
>
<div class="masonry-with-columns">
<NoticeCard
v-for="(notice, idx) in notices"
:key="idx"
v-bind.sync="notice"
></NoticeCard>
</div>
</v-container>
</template>
import NoticeCard from '@/components/common/Notices/NoticeCard';
export default {
data() {
return {
notices: []
}
},
components:{
NoticeCard
},
methods: {
getNotices() {
axiosRequest.get('/get-cards').then((response) => {
if ( response.status === 200 )
this.notices = response.data[0];
}).catch(e => axiosResponseErrorHandler(this, e));
},
}
}
</script>
<style scoped>
.masonry-with-columns {
columns: 3 400px;
column-gap: 10px;
max-width: 100%;
}
.masonry-with-columns div {
display: inline-block;
width: 100%;
}
</style>
Comments
Upvotes: 0
Reputation: 7781
No way (Yet) to solve this by Vuetify API.
Related Github Feature
Req:
[Feature Request] Masonry Layout #4091
Use Javascript plugin. For example masonry.js.
Codepen Demo: https://codepen.io/ezra_siton/pen/gOpZqKr
<!-- https://vuetifyjs.com/en/ -->
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<div id="app">
<v-app>
<v-content>
<v-container>
<v-row class="masonry">
<v-col class="child" cols="12" sm="6">
<v-card class="pa-2" color="pink darken-1" dark>
<v-card-title>Card 1</v-card-title>
<v-card-text>
The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections form, Rackham. One of three columns
The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections form, Rackham.
</v-card-text>
</v-card>
</v-col>
<!-- card 2-->
<v-col class="child" cols="12" sm="6">
<v-card class="pa-2" color="orange darken-3" dark>
<v-card-title>Card 2</v-card-title>
<v-card-text>
One The standard chunk of Lorem Ipsum used since the 1500s is
</v-card-text>
</v-card>
</v-col>
<!-- card 3 -->
<v-col class="child" cols="12" sm="6">
<v-card class="pa-2" color="#385F73" dark >
<v-card-title>Card 3</v-card-title>
<v-card-text>
The chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections form, Rackham.
</v-card-text>
</v-card>
</v-col>
<!-- card 4 -->
<v-col class="child" cols="12" sm="6">
<v-card class="pa-2" color="blue darken-4" dark >
<v-card-title>Card 4</v-card-title>
<v-card-text>
The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections form, Rackham.
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</v-content>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
<script src="https://unpkg.com/[email protected]/dist/masonry.pkgd.min.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
mounted: function () {
// Code that will run only after the
// entire view has been rendered
var msnry = new Masonry( '.masonry', {
// options
itemSelector: "[class*='col-']",
});
}
})
</script>
Step 1/3: CDN before body
Link directly to Masonry files on unpkg.
<script src="https://unpkg.com/[email protected]/dist/masonry.pkgd.min.js"></script>
-or- Install with npm: npm install masonry-layout
and use import import Masonry from 'masonry-layout'
Step 2/3: HTML - Set container element
Masonry works on a container grid element with a group of child items.
Add a class
(or id
) to your flexbox grid (Set as container element
).
masonry
in this example (Use any name you want).
<v-row class="masonry">
<v-col class="child" cols="12" sm="6">
<v-card class="pa-2" outlined >
..rest of the code
Step 3/3: Initialize with vanilla js
new Masonry( elem, options )
3.1: Use .masonry
as a container element argument.
3.2: Inside options object - set itemSelector
to:
itemSelector: "[class*='col-']"
[class*='col-']
: Wildcard selector (Select any class Contains col
. For example: .col-6
-or- .col-md-2
==> DRY // Clean solution)
I load the script inside vue mounted() lifecycle hook (After the components added to the DOM).
new Vue({
el: '#app',
vuetify: new Vuetify(),
mounted: function () {
// Code that will run only after the
// entire view has been rendered
var msnry = new Masonry( '.masonry', {
// options
itemSelector: "[class*='col-']",
});
}
})
One more option is to use flexbox/Grid and Custom CSS, in my opinion, this is too much code & ideas for such a simple task. Related article:
https://css-tricks.com/piecing-together-approaches-for-a-css-masonry-layout/
Upvotes: 8
Reputation: 678
If you are using VueJs and Vuetify then try to use vue.js masonry. With vue-masony, all you need to do is v-row
and v-col
instead of div
.
<v-row v-masonry transition-duration="0.3s" item-selector=".item">
<v-col v-masonry-tile class="item" cols="12" v-for="(content_obj, index) in class_contents" key="`content${index}`" sm="3" >
...
</v-col>
</v-row>
Upvotes: 1