Categories: UI/UX, Frontend
Tools: Gulp, SASS, Figma, Illustrator
Project Overview
What: CSS Zen Garden, a project focused on implementing UI design by editing only the CSS and without altering the HTML code.
Why: This project challenges and showcases our skills with advanced CSS concepts, demonstrating the power of CSS alone, without relying on other web technologies like JavaScript. It serves as a valuable learning opportunity, especially for seasoned developers who may face similar constraints where they can only modify CSS without changing the underlying HTML structure.
Logo
I had the option to style the heading text or replace it with a custom logo. I chose to create a logo to give users an instant visual representation of the design style.
UI Design
The design was inspired by the Mid-Century Modern style, featuring a minimal base layout with an emphasis on typography, white space, and color usage. Headings and buttons draw the most attention through contrasting colors, with offset fills and strokes that align with the overall design aesthetic.
Colors
#FED955
rgb(254, 17, 85)
#FECA12
rgb(254, 202, 18)
#CA9E01
rgb(202, 158, 1)
#C4423F
rgb(196, 66, 63)
#2EC4B6
rgb(46, 196, 182)
#F3E8EE
rgb(243, 232, 238)
Typography
Technical Implementations
CSS Custom Properties
A lot of the complexities required for the site were reduced by the use of CSS Custom Properties (also know as CSS Variables). To achieve this, I created a mixin that allowed me to easily create and update the values of the custom properties in a consistent manner.
utilities/_custom-properties.scss
@use 'sass:map';
$custom-properties: ();
@mixin init-property($name, $value) {
$custom-properties: map.merge(
$custom-properties,
(
$name: $value,
)
);
}
@mixin create-property($name, $value) {
--#{$name}: #{$value};
}
@mixin create-root() {
:root {
@each $name, $value in $custom-properties {
@include create-property($name, $value);
}
}
}
_base.sass
\:root
+utilities.create-property("color-yellow", "#FED955")
+utilities.create-property("color-yellow-200", "#feca12")
+utilities.create-property("color-yellow-300", "#ca9e01")
+utilities.create-property("color-red", "#C4423F")
+utilities.create-property("color-sea-green", "#2EC4B6")
+utilities.create-property("color-white", "#F3E8EE")
+utilities.create-property("section-heading-color", variables.$color-yellow)
+utilities.create-property("m-top", 0)
variables/_color.sass
$color-yellow: var(--color-yellow)
$color-yellow-200: var(--color-yellow-200)
$color-yellow-300: var(--color-yellow-300)
$color-red: var(--color-red)
$color-sea-green: var(--color-sea-green)
$color-white: var(--color-white)
Handling Section colors
While using Custom properties made it easier to manage aspects of the design, I still need an efficient way to handle the colors for each section. At first, I thought that I could use nth-child selectors to target each section, but that quickly became difficult to manage. As a result, I created a new mixin that allowed me to set the background color, heading color, and link color for each section based on the parameter passed to the mixin.
utilities/_section-mixin.scss
@mixin section-mixin($color) {
@if $color == 'white' {
--section-background-color: transparent;
--section-heading-color: #{variables.$color-red};
--link__color: var(--section-heading-color);
} @else if $color == 'yellow' {
--section-background-color: #{variables.$color-yellow};
--section-heading-color: #{variables.$color-sea-green};
--link__color: var(--section-heading-color);
a {
color: #{variables.$color-sea-green};
}
} @else if $color == 'green' {
--section-background-color: #{variables.$color-sea-green};
--section-heading-color: #{variables.$color-yellow};
a {
--link__color: #{variables.$color-white};
&:hover {
background: lighten(#111, 20%);
}
}
} @else {
@error "Invalid color";
}
}
Contribution
Although I didn’t submit a new design to the CSS Zen Garden website, I made a valuable contribution by submitting a bug fix to the CSS Zen Garden GitHub repository. I discovered that attempting to download the original HTML file only produced a blank file. After forking the repository, I reviewed the code and identified the problem: the file paths were incorrectly set due to a change from $SERVER_ROOT
to $_SERVER['DOCUMENT_ROOT']
, causing the paths to no longer point to the correct files.
To resolve this, I updated examples/index.php
and examples/src.php
by adjusting the include paths to use absolute references within $_SERVER['DOCUMENT_ROOT']
, ensuring each file was properly located. Below are the key changes I made:
examples/index.php
ob_start();
// pull in the source file for output, assign to $file variable
- include($_SERVER['DOCUMENT_ROOT'] . "src.php");
+ include($_SERVER['DOCUMENT_ROOT'] . "/examples/src.php");
$file = ob_get_contents();
// close up buffering
examples/src.php
// import URLs
- include($_SERVER['DOCUMENT_ROOT'] . "../includes/urls.php");
+ include($_SERVER['DOCUMENT_ROOT'] . "/includes/urls.php");
// import language file
- include($_SERVER['DOCUMENT_ROOT'] . "../lang/en.php");
+ include($_SERVER['DOCUMENT_ROOT'] . "/lang/en.php");
// import common functions & the design list
- include($_SERVER['DOCUMENT_ROOT'] . '../includes/masterlist.php');
- include($_SERVER['DOCUMENT_ROOT'] . "../includes/functions.php");
+ include($_SERVER['DOCUMENT_ROOT'] . '/includes/masterlist.php');
+ include($_SERVER['DOCUMENT_ROOT'] . "/includes/functions.php");
// reset current stylesheet to the example provided
$currentStyleSheet = "style.css";
// import the HTML template
- include($_SERVER['DOCUMENT_ROOT'] . "../includes/tmpl.php");
+ include($_SERVER['DOCUMENT_ROOT'] . "/includes/tmpl.php");
Conclusion
The CSS Zen Garden project allowed me to be more experimental with my design while adhering to the constraint of only changing the CSS. Throughout the process, I found applications for advanced CSS features I had learned in the past but hadn't yet had a chance to use. By leveraging CSS Custom Properties and SASS mixins, I was able to easily manipulate the design and create a consistent look and feel across the entire project. This experience was a valuable learning opportunity, allowing me to deepen my understanding of CSS architecture, and I'm excited to apply these techniques in future projects.