VueJS + CSS: grid template based on variable
Tags: vue, css, grid
Published: 2023-12-03 12:58:54

_This is my 10th write up on dev.to site. Example of CSS grid based on variable. Full source code is included as a flems.io link._

## CSS grid
CSS grid is one of technics for UI definition (you may know CSS Flexbox too).

Using CSS grid one can define **visual template** for content displayed on web page. 

As frontend developers we can use **"static template"** with no changes. Sometimes, there is a good practice to change layout based on condition defined with **Media Queries.** 

Did you know we can change our template via variable's value? Let's do this.

## CSS grid layout example
Assume we need place four buttons inside div and want change their positions.

HTML code:
```html
<div class="grid-area "> 
  <button class="btn-1 bg-blue" > A </button>
  <button class="btn-2 bg-blue" > B </button>
  <button class="btn-3 bg-blue" > C </button>
  <button class="btn-4 bg-blue" > D </button>
</div>
```
CSS code:
```css
.grid-area {
  display: grid;
  gap: 1rem;
}
```

This example shows fixed layout, there is nothing we can change. Let's do the magic.

Since we use VueJS, define variable holding class name we add to the div (grid countainer) and some CSS classes with different layout for our four buttons.
```js
...
  data: function(){
    return {
      template: "",
    }
  },
...
```
Example definitions of different CSS grid templates:
```css
.grid-area-4 {
  grid-template-areas:  "area1 area2 area3 area4"                 
}

.grid-area-2-2 {
  grid-template-areas:  "area1 area2"
                        "area3 area4"
}

.grid-area-1-2-1 {
  grid-template-areas:  "area1 area1"
                        "area2 area3"
                        "area4 area4"
}

.grid-area-2-1-1 {
  grid-template-areas:  "area1 area2"
                        "area3 area3"
                        "area4 area4"
}

.grid-area-1-1-2 {
  grid-template-areas:  "area1 area1"
                        "area2 area2"
                        "area3 area4"
}
```

Each button has its own class .btn-1, .btn-2 etc.
```css
.btn-1 {
  grid-area: area1;
}

.btn-2 {
  grid-area: area2;
}

.btn-3 {
  grid-area: area3;
}

.btn-4 {
  grid-area: area4;
}
```

A small change of HTML code is enough to do the magic:
```html
<div class="grid-area " :class="template"> 
  <button class="btn-1 bg-blue" > A </button>
  <button class="btn-2 bg-blue" > B </button>
  <button class="btn-3 bg-blue" > C </button>
  <button class="btn-4 bg-blue" > D </button>
</div>
```
Using VueJS variable **template** we can define dynamic class and apply it to the div (grid container).

I suppose my explanation is clear, here you can see full source code and playground on [flems.io](https://flems.io/#0=N4IgtglgJlA2CmIBcAWArAOgMwEYA0IAzvAgMYAu8UyIGAFuWLCAaQPYB2hbCN7ssAIYAHYtQKFSAJx7MkAbQAMeRQF0CAMwgJCyeaA6CwiJLQZMWIdh0o2aAHgBGbKAE8ABAD4AOh3fv7KAgAN3doAF5vEBFhKM97AHog4J8OX397SjBhIUowqEjwQQg0kC90-wDk91IhQkJCgHMpaABaQSl4QXco9yRawXrCrJzBShw4nr9KjMcAV3JyThq6hqjHcg5WnHdHRtbHWDn4Xs93AEEAhPnFzlSZ2YWlvwGh9c3WgCZd-cPj0-cACErjdnvcHk4nstXmsQBstlgfgcjicymcAMIgqEccEzSG3F6rQrw1ooJF-VFedwAESxBNxV2SDPsJWEC3cwVaYBcJGG8GyuXgEzK5FcwngfIAHuReqNSPA6DwoPApHyBWN4O4AMTC8rTfwVDLVGFNFpQdqdbq9fpEqIjQWfSaGyr454rQawkk7PZcwSNeA2QQAy6JUF3Z2PAnut5wj7fH1gP0B8hBtFAulgiMBMOEj3Ej6IhNJwMAzGh7EMyNuk3vLZkov+ktp2nl+nOxJM9us9mc7nK2Bq0aUR0isUSu3waWyoTyxWwZWqifqvJakd6mbt422kDNNodLo9Mo2vNLofwLBO-UunPRz0fb37ZrwAPBjPhq9V6Hbknxx+dF9psCraZh+2bYre+YIkiT4AVSZbXBWWaul+J6xnW0H-qUVItghbZXh2ITMt25AclyPIDqegoXqO4pSjKZRygqSoqoOgratR66VBUiT2hqqShi4rieJYxBkOQECcLopifEgiggAAvngBhGCYtAAFa6KwnC2OQNC+MEHTuDE7jhO4ABqxwYNIXSUOcwjCAAFMAFS8ZQSCHlqiYlFEeAVFAYyCO5GhzBwFASRwDkAJTOVenTkHMUh+DFDzuK5QruVEu7mvughfF8PlZmlMmHllFpdNseXCr5oFpVgGU7maZW5Z8FVVc68kVIpFTGOQipQIQ7kxZ1vjyZFGDciF5AOQA5FqMTTZFADcClKSAhjGDQVn1JY1g6TQ5iwO4yXuBo2mtIQEAAF7wO5OAABzCJKi0jb4vgAFRHRUp02OdV03e4OCdGAz0cB1aQcBgpU5Z90zOFIC7uYoj3uNwsDQLsKIg-4QSEKMrjuVlWPuI0Ii3UDINg74kONTlpIw-4pVpU1A0GtElo7Dl3w5YiOUoL0KUC1xoOvRDUOWnl3zHYz-Jnsz7mHjlHOWiOWaC2rCuWjzlp8yAL3g9Te7izglX08TjVMzlLMa10Ss21EqvqwLUSc0Zmv26BjtO2zXRkrz7uU6LNPiy1xs7FL5sy4Kcus4rrtdCrHuew8zua3HgjUQ7Sdcd7gi+9r-siwb2VGxVksVNLy7wNH1uCLbtfu1n6sp-HacJ43avN+nac63rvg3sdjiCKQADWzRsCF5r8GwUjuYcQ-D0TcMIwDyOo+jc8j0TU8z+4ADudAQJQROQFsu-QL17kAGzkxUwiCDAJSNIjGCfGgN+w9PC6tFI98QHMLOKBfm-fkFNC5elNmLLo7lFagP1j+CBQcoGt1gVTEkiJw6GyQdzFBEMSRkgwcXLB2scEYB9BSU2g8R5jwnq0bes9Ma91wfsRMjYUwUPntQjgk8eDT3ciw5MggSE+hgklColDR4yBoXQ9w-kpASOfBwHBxFTZnygBfGoghYCkAcjgRQihgi73cK0AGGAADswCwBLVvvfIIHAn7uEAa-d+-hExSEaCUVoSxhDPwscfDo7itjOFuGAW6GBfGMJFpEjgIkSDwDCpJGgdU5LyXUCANGHBh5SX0GtFSNBgiWUaLANgg9YAYA0pYBKcgQAMHIKIJACQEghWEKPKybAwAJHyfAAAAlgbAGAACcSQICEHIB0gpRSSllM0iAUU4oaCSBaMIXSKT5JAA)

Hope this help you :-)