I have the following code CODEPEN
HTML
body
#__nuxt
#__layout
//- CSS Grid
.news-item(:key="item.feed_item_id" :ref="item.feed_item_id" role="listitem" tabindex="0")
.news-item-pubdate 1m
.news-item-title(:style="titleStyle") {{item.title}}
span.news-item-link example.com
.news-item-likes
span.icon.is-small.news-item-vote-icon
i.fa.fa-xs.fa-thumbs-up
span.news-item-vote-count {{item.likes}}
.news-item-dislikes
span.icon.is-small.news-item-vote-icon
i.fa.fa-xs.fa-thumbs-down
span.news-item-vote-count {{item.dislikes}}
.news-item-bullish
span.icon.is-small.news-item-vote-icon
i.fa.fa-xs.fa-arrow-up
span.news-item-vote-count {{item.bullish}}
.news-item-bearish
span.icon.is-small.news-item-vote-icon
i.fa.fa-xs.fa-arrow-down
span.news-item-vote-count {{item.bearish}}
.news-item-comments
span.icon.is-small.news-item-vote-icon
i.fa.fa-xs.fa-comment-alt
span.news-item-vote-count 0
.news-item-tags.has-text-right(:style="tagStyle")
.news-item-tag(v-for='(tag, i) in item.tags' :key='item.tag' @click.stop="updateTag(tag)")
a.button.is-paddingless.is-small.is-uppercase.is-text
|{{tag}}
span(v-if="lineCountTag - 1 === i && item.tags.length > lineCountTag") ...
span(v-else)
//- Flexbox
.news-item2(:key="item.feed_item_id" :ref="item.feed_item_id" role="listitem" tabindex="0")
.news-item-pubdate-wrapper
.news-item-pubdate2 1m
.news-item-content-wrapper
.news-item-title-wrapper
.news-item-title2(:style="titleStyle") {{item.title}}
span.news-item-link2 example.com
.news-item-votes-wrapper
.news-item-likes2
span.icon.is-small.news-item-vote-icon2
i.fa.fa-xs.fa-thumbs-up
span.news-item-vote-count2 {{item.likes}}
.news-item-dislikes2
span.icon.is-small.news-item-vote-icon2
i.fa.fa-xs.fa-thumbs-down
span.news-item-vote-count2 {{item.dislikes}}
.news-item-bullish2
span.icon.is-small.news-item-vote-icon2
i.fa.fa-xs.fa-arrow-up
span.news-item-vote-count2 {{item.bullish}}
.news-item-bearish2
span.icon.is-small.news-item-vote-icon2
i.fa.fa-xs.fa-arrow-down
span.news-item-vote-count2 {{item.bearish}}
.news-item-comments2
span.icon.is-small.news-item-vote-icon2
i.fa.fa-xs.fa-comment-alt
span.news-item-vote-count2 0
.news-item-tags-wrapper
.news-item-tags2.has-text-right(:style="tagStyle")
.news-item-tag2(v-for='(tag, i) in item.tags' :key='item.tag' @click.stop="updateTag(tag)")
a.button.is-paddingless.is-small.is-uppercase.is-text
|{{tag}}
span(v-if="lineCountTag - 1 === i && item.tags.length > lineCountTag") ...
span(v-else)
CSS
/**
Using CSS GRID
*/
:root {
--border-color: lightgray;
}
$grey: hsl(0, 0%, 48%);
$grey-light: hsl(0, 0%, 71%);
$size-7: 0.75rem;
$warning-light: hsl(48, 100%, 67%);
.news-item {
display: grid;
grid-template-areas:
'time title title title title title title tags'
'time likes dislikes bullish bearish comments . tags';
grid-template-rows: 1fr auto;
grid-template-columns: auto auto auto auto auto auto 1fr auto;
border-bottom: 1px solid var(--border-color);
}
.news-item-title {
grid-area: title;
overflow: hidden;
}
.news-item-likes {
grid-area: likes;
}
.news-item-dislikes {
grid-area: dislikes;
}
.news-item-bullish {
grid-area: bullish;
}
.news-item-bearish {
grid-area: bearish;
}
.news-item-comments {
grid-area: comments;
}
.news-item-tags {
grid-area: tags;
overflow: hidden;
}
a.news-item-tag {
color: $grey;
text-decoration: none;
}
.news-item-link {
color: $grey;
font-size: $size-7;
}
.news-item-pubdate {
grid-area: time;
align-self: center;
color: $grey-light;
font-size: $size-7;
}
.news-item-vote-icon {
color: $grey-light;
margin-right: 0.1rem;
}
.news-item-vote-count {
font-size: 0.75rem;
margin-right: 0.5rem;
color: $grey-light;
}
.news-item-selected {
background: $warning-light;
}
/** https://stackoverflow.com/questions/23608346/how-to-style-a-div-like-the-button-element */
.news-item {
cursor: pointer;
user-select: none;
}
a.button.is-paddingless.is-small.is-uppercase.is-text {
text-decoration: none;
line-height: 1.5;
color: $grey;
}
/**
Using FLEXBOX
*/
.news-item2 {
display: flex;
align-items: center;
border-bottom: 1px solid var(--border-color);
}
.news-item-content-wrapper {
flex: 1;
display: flex;
flex-direction: column;
}
.news-item-votes-wrapper {
display: flex;
}
.news-item-title2 {
overflow: hidden;
}
.news-item-link2 {
color: $grey;
font-size: $size-7;
}
.news-item-pubdate2 {
grid-area: time;
align-self: center;
color: $grey-light;
font-size: $size-7;
}
.news-item-vote-icon2 {
color: $grey-light;
margin-right: 0.1rem;
}
.news-item-vote-count2 {
font-size: 0.75rem;
margin-right: 0.5rem;
color: $grey-light;
}
.news-item-tags2 {
overflow: hidden;
}
Vue JS
new Vue({
el: "#__nuxt",
data() {
return {
item: {
feed_item_id: 1,
title: 'The first one is made with a grid layout while the second one is made with a flex layout. The templates are different, how do I load the right one based on what is supported by the browser?',
tags: ['trump', 'putin', 'defi'],
likes: 10,
dislikes: 5,
bullish: 6,
bearish: 0,
},
lineCountTag: 2,
lineCountTitle: 2,
heightPerLineTag: 30,
heightPerLineTitle: 24,
};
},
computed: {
tagStyle() {
return {
height: this.heightPerLineTag * this.lineCountTag + "px",
maxHeight: this.heightPerLineTag * this.lineCountTag + "px"
};
},
titleStyle() {
return {
height: this.heightPerLineTitle * this.lineCountTitle + "px",
maxHeight: this.heightPerLineTitle * this.lineCountTitle + "px"
};
}
}
});
- I have made 2 rows, first row is made with grid layout
- second one uses flexbox layout
- I want a Vue component which basically can load one of them depending on whether the browser supports flexbox or grid
- The problem is the templates are different from each other
- How do I do this?