This is my solution to the Art gallery website challenge on Frontend Mentor.
Users should be able to:
- View the optimal layout for each page depending on their device's screen size
- See hover states for all interactive elements throughout the site
- Bonus: Use Leaflet JS to create an interactive location map with custom location pin
- Solution URL: Art gallery website
- Live Site URL: fm-modern-art-gallery.netlify.app
- Semantic HTML5 markup
- Mobile-first approach
- Flexbox
- CSS Grid
- GSAP animation
- TypeScript
- Sass
- webpack
- While I have been using Sass CSS preprocessor for a long time, I primarily used it for its variables and nested rules features. As I spent more time reviewing other projects I noticed that I could gain efficiency in my CSS authoring by implementing Sass maps in conjunction with
At-rules
like@each
etc. I started using these to generate helper classes in my project.
$colors: (
dark: (
color-1: rgba(68, 68, 68, 1),
color-2: rgba(21, 21, 21, 1)
)
);
@each $color, $shade in $colors {
@each $key, $value in $shade {
.text-#{"" + $color}-#{$key} {
color: #{$value} !important;
}
}
}
// CSS Output
.text-dark-color-1 {
color: #444444 !important;
}
.text-dark-color-2 {
color: #151515 !important;
}
- I started using custom CSS properties as this allows me to better organise my CSS. Variables that are specific to a component are located in the same module, the set of rules are less repetitive as I can leverage on the cascade.
.card {
--h-spacing: #{toRem(24px)};
--v-spacing: #{toRem(48px)};
&__content {
padding: var(--v-spacing) var(--h-spacing);
}
@include media-breakpoint(md) {
--h-spacing: #{toRem(28px)};
--v-spacing: #{toRem(69px)};
}
@include media-breakpoint(xl) {
--h-spacing: #{toRem(48px)};
--v-spacing: #{toRem(52px)};
}
}
- Getting the grid as per the design was more challenging than I thought. I initially started with by defining the height of each row for the main content for different viewport widths but I soon realised that this was difficult to maintain. I finally found an efficient solution by using the
minmax()
function with thegrid-template-columns
andgrid-template-rows
properties.
.content-rows {
grid-template-rows: repeat(auto-fit, minmax(toRem(200px), 1fr));
}
- I was able implement responsive images by using the
<picture>
and<source>
elements in conjunction with the<img/>
element. This allows me to serve images in portrait mode on smaller viewports.
<div class="card">
<div class="card__content">
<picture>
<source media="(max-width: 767px)" srcset="assets/images/home/mobile/image-grid-1.jpg">
<source media="(max-width: 768px)" srcset="assets/images/home/tablet/image-grid-1.jpg">
<source media="(max-width: 1200px)" srcset="assets/images/home/desktop/image-grid-1.jpg">
<img src="assets/images/home/desktop/[email protected]" alt="Contemporary Art" />
</picture>
</div>
</div>
- Responsive grid in 2 minutes with CSS grid layout
- Responsive grid magazine layout in just 20 line of CSS
- Christopher Adolphe
- Frontend Mentor - @christopher-adolphe
- Twitter - @cadolphe23