Created
June 26, 2022 15:12
-
-
Save MarceauKa/3708bdfe4bce74fd73181ac4ef9556b7 to your computer and use it in GitHub Desktop.
Grid, data labels and favorites
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<title>Data labels, Favorites and Grid</title> | |
<link rel="preconnect" href="https://fonts.googleapis.com"> | |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet"> | |
<style type="text/css"> | |
/** Base styles **/ | |
* { | |
margin: 0; | |
padding: 0; | |
box-sizing: border-box; | |
} | |
body { | |
font-size: 16px; | |
line-height: 20px; | |
font-family: Roboto, sans-serif; | |
color: black; | |
} | |
.wrapper { | |
width: 100%; | |
max-width: 1024px; | |
margin: 0 auto; | |
padding: 2rem 1rem; | |
display: grid; | |
grid-template-columns: 1fr; | |
gap: 2rem; | |
} | |
/** Cards **/ | |
.card { | |
position: relative; | |
display: flex; | |
flex-direction: column; | |
width: 100%; | |
overflow: hidden; | |
box-shadow: 0 1rem 2rem 1rem rgba(0, 0, 0, .125); | |
border-radius: 1rem; | |
} | |
.card img { | |
width: 100%; | |
max-height: 240px; | |
object-fit: cover; | |
flex-grow: 1; | |
} | |
.card .content { | |
position: relative; | |
padding: .75rem; | |
display: flex; | |
flex-direction: column; | |
gap: .5rem; | |
} | |
.card .content h2 {} | |
.card .content p {} | |
.card[data-new]::before { | |
content: "Nouveau"; | |
position: absolute; | |
top: 1rem; | |
right: 1rem; | |
background-color: #b3ffb3; | |
color: green; | |
padding: .25rem .5rem; | |
font-size: .75rem; | |
} | |
.card button { | |
position: absolute; | |
right: 1rem; | |
top: 1.25rem; | |
width: 2rem; | |
height: 2rem; | |
border-radius: 100%; | |
border: 0; | |
background: none; | |
} | |
.card button svg { | |
fill: transparent; | |
stroke: black; | |
transition: all 200ms linear; | |
stroke-width: 1; | |
pointer-events: none; | |
} | |
.card button:hover svg, | |
.card button.active svg { | |
fill: #dcdc1e; | |
stroke: #dcdc1e; | |
} | |
/** Responsive MD **/ | |
@media screen and (min-width: 660px) { | |
.wrapper { | |
grid-template-columns: 1fr 1fr; | |
} | |
} | |
/** Responsive LG **/ | |
@media screen and (min-width: 900px) { | |
.wrapper { | |
grid-template-columns: 1fr 1fr 1fr; | |
grid-template-rows: 1fr 1fr; | |
} | |
.card.full-h { | |
grid-row: span 2; | |
} | |
.card img { | |
max-height: 100%; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div class="wrapper"> | |
<div class="card"> | |
<img src="https://images.unsplash.com/photo-1567767292278-a4f21aa2d36e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80" /> | |
<div class="content"> | |
<h2>Toulouse</h2> | |
<p>188 000 €</p> | |
<button id="toulouse" data-favorite> | |
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" /></svg> | |
</button> | |
</div> | |
</div> | |
<div class="card" data-new> | |
<img src="https://images.unsplash.com/photo-1585412727339-54e4bae3bbf9?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80" /> | |
<div class="content"> | |
<h2>Paris</h2> | |
<p>163 000 €</p> | |
<button id="paris" data-favorite> | |
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" /></svg> | |
</button> | |
</div> | |
</div> | |
<div class="card full-h"> | |
<img src="https://images.unsplash.com/photo-1589834390005-5d4fb9bf3d32?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80" /> | |
<div class="content"> | |
<h2>Montpellier</h2> | |
<p>293 000 €</p> | |
<button id="montpellier" data-favorite> | |
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" /></svg> | |
</button> | |
</div> | |
</div> | |
<div class="card"> | |
<img src="https://images.unsplash.com/photo-1554995207-c18c203602cb?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80" /> | |
<div class="content"> | |
<h2>Rennes</h2> | |
<p>201 000 €</p> | |
<button id="rennes" data-favorite> | |
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" /></svg> | |
</button> | |
</div> | |
</div> | |
<div class="card"> | |
<img src="https://images.unsplash.com/photo-1560448204-e02f11c3d0e2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1740&q=80" /> | |
<div class="content"> | |
<h2>Bordeaux</h2> | |
<p>234 000 €</p> | |
<button id="bordeaux" data-favorite> | |
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" /></svg> | |
</button> | |
</div> | |
</div> | |
</div> | |
<script type="text/javascript"> | |
class Favorites { | |
constructor(selector, className) { | |
this.className = className | |
this.els = Array.from(document.querySelectorAll(selector)) | |
this.readStorage() | |
this.bindEvents() | |
} | |
bindEvents() { | |
this.els.forEach(item => { | |
let id = item.getAttribute('id') | |
if (this.favorites.includes(id)) { | |
item.classList.toggle(this.className) | |
} | |
item.addEventListener('click', (event) => { | |
event.preventDefault() | |
this.toggleElement(event.target) | |
}) | |
}) | |
} | |
toggleElement(element) { | |
element.classList.toggle(this.className) | |
let id = element.getAttribute('id') | |
if (this.favorites.includes(id)) { | |
this.favorites.splice(this.favorites.indexOf(id), 1) | |
} else { | |
this.favorites.push(id) | |
} | |
this.writeStorage() | |
} | |
readStorage() { | |
let favorites = window.localStorage.getItem('favorites') | |
this.favorites = favorites ? JSON.parse(favorites) : [] | |
} | |
writeStorage() { | |
window.localStorage.setItem('favorites', JSON.stringify(this.favorites)) | |
} | |
} | |
new Favorites('[data-favorite]', 'active') | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment