Published on February 5, 2022 Updated on June 13, 2024

Pure CSS Framework

Hey! So you came here to see another CSS framework? right? So time to worry, I am telling you how to create your CSS framework instead of using one. So let’s begin!


But why?

Glad you asked now, go to a bootstrap site and then go to a vanilla CSS site. Now you see the difference I’m talking about.
When the page with Bootstrap loads in 2s the page with vanilla CSS is loading in less than 1s ?.

Let’s get started!

So we’ll build this using pure CSS!

1. Create the page with the framework

Yes, do this first in development. And follow the other steps.

2. Inspect the styles

So this is the tricky part to do but wait! There are Firefox devtools for the rescue.

Now if you select an element and go to the computed tab there is the CSS we need! So I’ll copy the HTML first.

<div class="modal-sheet" tabindex="-1" role="dialog" id="modalSheet">
	<div class="modal-dialog" role="document">
		<div class="modal-content rounded-6 shadow">
			<div class="modal-header border-bottom-0">
				<h5 class="modal-title">Modal title</h5>
				<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
			<div class="modal-body py-0">
					This is a modal sheet, a variation of the modal that docs itself to the bottom of the
					viewport like the newer share sheets in iOS.
			<div class="modal-footer flex-column border-top-0">
				<button type="button" class="btn btn-lg btn-primary w-100 mx-0 mb-2">Save changes</button>
				<button type="button" class="btn btn-lg btn-light w-100 mx-0" data-bs-dismiss="modal">

I’ll reduce some classes ?

<div class="modal-sheet">
	<div class="dialog" role="document">
		<div class="content">
			<div class="header">
				<h5 class="title">Modal title</h5>
				<button type="button" class="close"></button>
			<div class="body">
					This is a modal sheet, a variation of the modal that docs itself to the bottom of the
					viewport like the newer share sheets in iOS.
			<div class="footer">
				<button type="button" class="btn primary">Save changes</button>
				<button type="button" class="btn" data-bs-dismiss="modal">Close</button>

And before we start with the CSS, I’ll apply some fixes.

body {
	margin: 0;
	padding: 0;
		'Segoe UI',
		'Helvetica Neue',
		'Noto Sans',
		'Liberation Sans',
		'Apple Color Emoji',
		'Segoe UI Emoji',
		'Segoe UI Symbol',
		'Noto Color Emoji';

*:before {
	box-sizing: border-box;

So we will get something like this

Now, we’ll first create the overlay. So with just basic CSS knowledge, you can do this

.modal-sheet {
	display: flex;
	position: fixed;
	top: 0;
	left: 0;
	height: 100%;
	width: 100%;
	align-items: center;
	justify-content: center;

Now we have the items centred. Now, we need the background colour, How do we find that? easy! Select the element and go to the computed styles tab and there you will see its background-colour

Now I’ll add it.

Nice. The next thing is to style the modal, so for this to I’ll do the same stuff.

.dialog {
	background: white;
	padding: 19px;
	max-width: 380px;
	border-radius: 10px;
	border: 1px solid rgba(0, 0, 0, 0.2);

Yay! ?? but wait there’s more. So I’ll style the other stuff too.

.header {
	display: flex;
	align-items: center;
	justify-content: space-between;
.title {
	margin: 0;
	font-size: 20px;
	font-weight: 400;
	color: rgb(33, 37, 41);
.close {
	border: none;
	background: transparent
		url("data:image/svg+xml,%3csvg xmlns='' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e")
		center/1em auto no-repeat;
	height: 32px;
	width: 32px;
	opacity: 0.6;
	border-radius: 4px;
.close:hover {
	opacity: 1;
.close:focus {
	box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
	opacity: 1;

.footer {
	display: grid;

So far we have this,

Now, I’ll create an SCSS mixin for the buttons.

@mixin button($color) {
	color: #fff;
	background: $color;
	&:hover {
		background: darken($color, 10%);
	&:active {
		background: darken($color, 20%);
	&:focus {
		box-shadow: 0px 0px 0px 4px rgba($color, 0.5);

.btn {
	padding: 0.5rem 1rem;
	margin-bottom: 10px;
	border: none;
	font-size: 1.25rem;
	font-family: inherit;
	border-radius: 4px;
	transition: all 0.2s ease;
	background: transparent;

	&:focus {
		box-shadow: 0px 0px 0px 4px rgba(211, 212, 213, 0.5);

	&.primary {
		@include button(#0d6efd);

And we’re done!

So you see how easy was that? You just need some patience and some effort and you can build optimized websites fast. So see you next time!

Something wrong or just found a typo? Edit this page on GitHub and make a PR!