JSFiddle - React, Tailwind, and code Playground
by Alexandru Gatea
HTML
<div class="grid">
<div class="grid-item">
<div class="grid-item-content">
<div class="grid-item-content-inner">
<h2 class="grid-item-header">Cluj-Napoca</h2>
<h3 class="grid-item-subheader">/ Europe</h3>
<address>
<span>Bd. 21 Decembrie 1989, No. 77</span>
<span>Building E, Ground Floor</span>
<span>400124 Cluj-Napoca, Romania</span>
<span>Phone +40 (0) 364 730 191</span>
<span>Fax +40 (0) 364 730 190</span>
</address>
</div>
</div>
</div>
<div class="grid-item">
<div class="grid-item-content">
<div class="grid-item-content-inner">
<h2 class="grid-item-header">Cluj-Napoca</h2>
<h3 class="grid-item-subheader">/ Europe</h3>
<address>
<span>Bd. 21 Decembrie 1989, No. 77</span>
<span>Building E, Ground Floor</span>
<span>400124 Cluj-Napoca, Romania</span>
<span>Phone +40 (0) 364 730 191</span>
<span>Fax +40 (0) 364 730 190</span>
</address>
</div>
</div>
</div>
<div class="grid-item">
<div class="grid-item-content">
<div class="grid-item-content-inner">
<h2 class="grid-item-header">Cluj-Napoca</h2>
<h3 class="grid-item-subheader">/ Europe</h3>
<address>
<span>Bd. 21 Decembrie 1989, No. 77</span>
<span>Building E, Ground Floor</span>
<span>400124 Cluj-Napoca, Romania</span>
<span>Phone +40 (0) 364 730 191</span>
<span>Fax +40 (0) 364 730 190</span>
</address>
</div>
</div>
</div>
<div class="grid-item">
<div class="grid-item-content">
<div class="grid-item-content-inner">
<h2 class="grid-item-header">Cluj-Napoca</h2>
<h3 class="grid-item-subheader">/ Europe</h3>
<address>
<span>Bd. 21 Decembrie 1989, No. 77</span>
<span>Building E, Ground Floor</span>
<span>400124 Cluj-Napoca,...
SCSS
* {
box-sizing: border-box;
font-family: "Segoe UI", sans-serif;
}
$mq: 768px;
.grid {
padding: 30px;
grid-gap: 30px;
display: grid;
background: #212121;
@media (min-width: #{$mq}) {
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
grid-auto-rows: 1fr;
max-width: 1200px;
margin: auto;
&-item-content {
position: relative;
&:hover {
z-index: 1000;
box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.4);
cursor: pointer;
}
@media (min-width: #{$mq}) {
position: relative;
width: 100%;
height: 0;
padding-bottom: 100%;
}
&-inner {
background: #424242;
padding: 30px;
color: #fff;
@media (min-width: #{$mq}) {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: space-between;
}
}
}
&-item {
&-header {
font-size:1.375rem;
@media (min-width: 480px) {
font-size: calc(1.375rem + ((1vw - 4.8px) * 3.6111));
}
@media (min-width: 1200px) {
font-size: 48px;
}
}
&-subheader {
flex-grow: 1;
font-size: 1.25rem;
@media (min-width: 480px) {
font-size: calc(1.25rem + ((1vw - 4.8px) * 1.6667));
}
@media (min-width: 1200px) {
font-size: 32px;
}
@media (max-width: 767px) {
margin-bottom: 30px;
}
}
address {
span {
display: block;
margin-bottom: 3px;
opacity: 0.8;
}
}
}
}
JavaScript
var VanillaTilt = function() {
"use strict";
class t {
constructor(e, i = {}) {
if (!(e instanceof Node)) throw "Can't initialize VanillaTilt because " + e + " is not a Node.";
this.width = null, this.height = null, this.clientWidth = null, this.clientHeight = null, this.left = null, this.top = null, this.gammazero = null, this.betazero = null, this.lastgammazero = null, this.lastbetazero = null, this.transitionTimeout = null, this.updateCall = null, this.event = null, this.updateBind = this.update.bind(this), this.resetBind = this.reset.bind(this), this.element = e, this.settings = this.extendSettings(i), this.reverse = this.settings.reverse ? -1 : 1, this.glare = t.isSettingTrue(this.settings.glare), this.glarePrerender = t.isSettingTrue(this.settings["glare-prerender"]), this.fullPageListening = t.isSettingTrue(this.settings["full-page-listening"]), this.gyroscope = t.isSettingTrue(this.settings.gyroscope), this.gyroscopeSamples = this.settings.gyroscopeSamples, this.elementListener = this.getElementListener(), this.glare && this.prepareGlare(), this.fullPageListening && this.updateClientSize(), this.addEventListeners(), this.updateInitialPosition()
}
static isSettingTrue(t) {
return "" === t || !0 === t || 1 === t
}
getElementListener() {
if (this.fullPageListening) return window.document;
if ("string" == typeof this.settings["mouse-event-element"]) {
const t = document.querySelector(this.settings["mouse-event-element"]);
if (t) return t
}
return this.settings["mouse-event-element"] instanceof Node ? this.settings["mouse-event-element"] : this.element
}
addEventListeners() {
this.onMouseEnterBind = this.onMouseEnter.bind(this), this.onMouseMoveBind = this.onMouseMove.bind(this), this.onMouseLeaveBind = this.onMouseLeave.bind(this), this.onWindowResizeBind = this.onWindowResize.bind(this), this.onDeviceOrientationBind = this.onDeviceOrientation.bind(this),...