100 Days of CSS: Day 9

February 13, 2025

Rainy Night: The perfect time of day and the perfect weather to program in peace. The raindrops even shatter on the ground.

Unsplash ↗

Project Structure

The project consists of 3 main files:

HTML Structure

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam posuere erat at mi sagittis ultricies. Aenean cursus libero vitae odio congue volutpat.

<div class="frame">
	<div class="moon">        
		<!-- Craters will be dynamically
added here -->
	</div>
	<div class="hill-bg-1"></div>
	<div class="hill-bg-2"></div>
	<div class="hill-fg-1"></div>
	<div class="hill-fg-2"></div>
	<div class="hill-fg-3"></div>
	<div class="front">
		<div class="temperature">12°</div>
		<div class="info">
			Wind:E 7km/h <br> Humidity:87%
		</div>
		<table class="preview">
			<tr>
				<td>Tue</td>
				<td>21° / 9°</td>
			</tr>
			<tr>
				<td>Wed</td>
				<td>23° / 10°</td>
			</tr>
		</table>
	</div>
</div>

CSS Styling

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam posuere erat at mi sagittis ultricies. Aenean cursus libero vitae odio congue volutpat.

@import url(https://fonts.googleapis.com/css?family=Open+Sans:300,400,700);

$drop-color: #7fc1f9;

// use only the available space inside the 400x400 frame
.frame {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 400px;
	height: 400px;
	margin-top: -200px;
	margin-left: -200px;
	border-radius: 2px;
	box-shadow: 1px 2px 10px 0 rgba(0, 0, 0, 0.3);
	background: #1A2238;
	color: #394568;
	font-family: "Open Sans", Helvetica, sans-serif;
	font-weight: 300;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	overflow:hidden;
}

.moon {
	position: absolute;
	width: 69px;
	height: 69px;
	top: 45px;
	left: 55px;
	border-radius: 50%;
	background: #f6edbd;
	overflow: hidden;
	box-shadow: 0 0 10px 0 #f6edbd;
	animation: rise 1s ease-out;

	.crater-1 {
		position: absolute;
		width: 11px;
		height: 11px;
		top: 9px;
		left: 28px;
		border-radius: 10px;
		background: #ece1a8;
	}

	.crater-2 {
		@extend .crater-1;
		top: 12px;
		left: 0;
	}

	.crater-3 {
		@extend .crater-1;
		top: 56px;
		left: 10px;
	}

	.crater-4 {
		@extend .crater-1;
		width: 6px;
		height: 6px;
		top: 37px;
		left: 49px;
	}

	.crater-5 {
		@extend .crater-4;
		top: 24px;
		left: 61px;
	}

	.crater-6 {
		@extend .crater-4;
		top: 55px;
		left: 33px;
	}

	.crater-7 {
		@extend .crater-4;
		top: 17px;
		left: 46px;
	}

	.crater-8 {
		@extend .crater-4;
		top: 28px;
		left: 27px;
	}

	.crater-9 {
		@extend .crater-4;
		top: 39px;
		left: 17px;
	}

	.crater-10 {
		@extend .crater-1;
		width: 4px;
		height: 4px;
		top: 25px;
		left: 15px;
	}

	.crater-11 {
		@extend .crater-10;
		top: 37px;
		left: 37px;
	}
}

.hill-bg-1 {
	position: absolute;
	z-index: 2;
	width: 337px;
	height: 281px;
	top: 200px;
	left: -58px;
	background: #26314f;
	border-radius: 50%;
}

.hill-bg-2 {
	@extend .hill-bg-1;
	top: 198px;
	left: 175px;
}

.hill-fg-1 {
	@extend .hill-bg-1;
	background: #303c5d;
	top: 250px;
	left: -140px;
}

.hill-fg-2 {
	@extend .hill-fg-1;
	top: 220px;
	left: 60px;
}

.hill-fg-3 {
	@extend .hill-fg-1;
	top: 250px;
	left: 292px;
}

.front {
	position: absolute;
	z-index: 10;
	width: 400px;
	height: 90px;
	left: 0px;
	bottom: 0px;
	background: #fff;

	.temperature {
		float: left;
		margin-left: 20px;
		font-size: 45px;
		line-height: 90px;
	}

	.info {
		float: left;
		margin: 25px 0 0 13px;
		font-size: 15px;
		line-height: 20px;
	}

	.preview {
		float: right;
		font-weight: 400;
		text-align: right;
		font-size: 15px;
		line-height: 20px;
		margin: 25px 30px 0 0;

		td {
			padding: 0 3px;
			text-transform: uppercase;

			&:first-child {
				font-weight: 300;
			}
		}
	}
}

@for $i from 1 through 10 {
	
	.raindrop-big-#{$i} {
		position: absolute;
		z-index: 20;
		left: (-20 + 38 * $i) + px;
		bottom: 90px;
		width: 8px;
		height: 8px;
		border-radius: 50%;
		background: $drop-color;
		animation: drop (0.7 + random(2) / 10) + s linear (random(50) / 25) + s infinite;
		animation-fill-mode: both;
		transform-origin: 50% 100%;

		&:before {
			position: absolute;
			content:'';
			display: block;
			top: -2px;
			left: 1px;
			width: 6px;
			height: 6px;
			background: $drop-color;
			border-radius: 3px;
		}

		&:after {
			position: absolute;
			content: '';
			display: block;
			top: -5px;
			left: 2px;
			width: 4px;
			height: 10px;
			background: $drop-color;
			border-radius: 50%;
		}
	}
	
	.raindrop-medium-#{$i} {
		@extend .raindrop-big-1;
		left: (-20 + 38 * $i) + px;
		opacity: 0.6;
		width: 6px;
		height: 6px;
		animation: drop (1.3 + random(2) / 10) + s linear (random(50) / 25) + s infinite;
		animation-fill-mode: both;
		
		&:before {
			top: -2px;
			left: 1px;
			width: 4px;
			height: 4px;
		}
		
		&:after {
			top: -4px;
			left: 2px;
			width: 2px;
			height: 6px;
		}
		
	}
	
	.raindrop-small-#{$i} {
		@extend .raindrop-big-1;
		left: (-20 + 38 * $i) + px;
		opacity: 0.3;
		width: 4px;
		height: 4px;
		animation: drop (1.9 + random(2) / 10) + s linear (random(50) / 25) + s infinite;
		animation-fill-mode: both;
		
		&:before {
			top: -2px;
			left: 1px;
			width: 2px;
			height: 2px;
		}
		
		&:after {
			top: -3px;
			left: 1px;
			width: 2px;
			height: 4px;
		}
		
	}
}

@keyframes drop {
	0% {
		transform: translate3d(40px, -320px, 0) scaleX(1) scaleY(1) rotate(17deg);
	}
	85% {
		transform: translate3d(0, 0, 0) scaleX(1) scaleY(1) rotate(17deg);
	}
	100% {
		transform: translate3d(0, 0, 0) scaleX(3) scaleY(0) rotate(0deg);
	}
}

@keyframes rise {
	from {
		transform: translate(-20px, 200px);
	}
	to {
		transform: translate(0, 0px);
	}
}

Javascript

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam posuere erat at mi sagittis ultricies. Aenean cursus libero vitae odio congue volutpat.

$(document).ready(function () {
	// Adding craters dynamically
	for (let i = 1; i <= 11; i++) {
		$(".moon").append('<div class="crater-' + i + '"> <div>');
	}

	// adding raindrops dynamically
	for (let i = 1; i <= 10; i++) {
		$(".frame").append('<div class="raindrop-big-' + i + '"></div>');
	}
	for (let i = 1; i <= 10; i++) {
		$(".frame").append('<div class="raindrop-med-' + i + '"></div>');
	}
	for (let i = 1; i <= 10; i++) {
		$(".frame").append('<div class="raindrop-small-' + i + '"></div>');
	}
});

Reflection