Introduction: In the realm of web development, providing informative feedback to users is crucial for enhancing their experience. Neumorphic design, characterized by soft shadows and subtle highlights, offers a modern and visually appealing approach to displaying notifications or toasts. In this tutorial, we’ll explore how to create interactive neumorphic toasts using HTML and CSS, allowing users to receive and dismiss various types of messages.
HTML Structure: Our HTML structure consists of a series of checkboxes representing different types of toasts, such as help, success, warning, and error. Each checkbox is associated with a corresponding toast message displayed in a div container. Additionally, we include labels for each checkbox to serve as triggers for displaying or hiding the respective toasts.
<input type="checkbox" name="t-help" id="t-help" checked>
<input type="checkbox" name="t-success" id="t-success" checked>
<input type="checkbox" name="t-warning" id="t-warning" checked>
<input type="checkbox" name="t-error" id="t-error" checked>
<div class="toast-panel">
<div class="toast-item help">
<div class="toast help">
<label for="t-help" class="close"></label>
<h3>Help!</h3>
<p>Do you have a problem? Just use this <a href="#">contact form</a>.</p>
</div>
</div>
<div class="toast-item success">
<div class="toast success">
<label for="t-success" class="close"></label>
<h3>Success!</h3>
<p>Your message has been sent successfully.</p>
</div>
</div>
<div class="toast-item warning">
<div class="toast warning">
<label for="t-warning" class="close"></label>
<h3>Warning!</h3>
<p>Sorry, there was a problem with your request.</p>
</div>
</div>
<div class="toast-item error">
<div class="toast error">
<label for="t-error" class="close"></label>
<h3>Error!</h3>
<p>Change a few things up and try submitting again.</p>
</div>
</div>
<div class="toast-icons">
<label for="t-help" class="toast-icon icon-help"></label>
<label for="t-success" class="toast-icon icon-success"></label>
<label for="t-warning" class="toast-icon icon-warning"></label>
<label for="t-error" class="toast-icon icon-error"></label>
</div>
</div>
HTMLCSS Styling: CSS serves as the backbone for styling our neumorphic toasts, leveraging variables for dynamic color and animation effects. We define properties for background colors, box shadows, and transition durations to achieve the neumorphic aesthetic. Additionally, we utilize keyframes for animating the appearance and disappearance of the toasts, creating a smooth and intuitive user experience.
@import url('https://fonts.googleapis.com/css2?family=Varela+Round&display=swap');
:root {
--tr: all 0.5s ease 0s;
--ch1: #05478a;
--ch2: #0070e0;
--cs1: #005e38;
--cs2: #03a65a;
--cw1: #c24914;
--cw2: #fc8621;
--ce1: #851d41;
--ce2: #db3056;
}
@property --bg-help {
syntax: '<percentage>';
inherits: false;
initial-value: -10%;
}
@property --bg-success {
syntax: '<percentage>';
inherits: false;
initial-value: 145%;
}
@property --bg-warning {
syntax: '<percentage>';
inherits: false;
initial-value: -55%;
}
@property --bg-error {
syntax: '<percentage>';
inherits: false;
initial-value: 112%;
}
@property --bsc {
syntax: '<color>';
inherits: false;
initial-value: red;
}
body {
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
display: flex;
align-items: center;
justify-content: flex-end;
flex-direction: column;
background: #1E1C27;
font-family: "Varela Round", sans-serif;
}
.toast-panel {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transition: var(--tr);
position: absolute;
padding: 0 1rem;
height: 100%;
}
.toast-item {
/*overflow: hidden;*/
max-height: 25rem;
transition: var(--tr);
position: relative;
animation: show-toast 4s ease 3s 1;
}
@keyframes show-toast {
0%, 50%, 100% { max-height: 0; opacity: 0; }
10%, 25% { max-height: 15rem; opacity: 1; }
}
.toast {
background: #fff;
color: #f5f5f5;
padding: 1rem 2rem 1rem 3rem;
text-align: center;
border-radius: 1rem;
position: relative;
font-weight: 300;
margin: 1rem 0;
text-align: left;
max-width: 16rem;
transition: var(--tr);
opacity: 1;
border: 0.15rem solid #fff2;
box-shadow: 0 0 1.5rem 0 #1a1f4360;
}
.toast:before {
content: "";
position: absolute;
width: 0.5rem;
height: calc(100% - 1.5rem);
top: 0.75rem;
left: 0.5rem;
z-index: 0;
border-radius: 1rem;
background: var(--clr);
}
.toast h3 {
font-size: 1.2rem;
margin: 0;
line-height: 1.35rem;
font-weight: 600;
position: relative;
color: var(--clr);
}
.toast p {
position: relative;
font-size: 0.95rem;
z-index: 1;
margin: 0.25rem 0 0;
color: #595959;
line-height: 1.3rem;
}
.close {
position: absolute;
width: 1.35rem;
height: 1.35rem;
text-align: center;
right: 1rem;
cursor: pointer;
border-radius: 100%;
}
.close:after {
position: absolute;
font-family: 'Varela Round', san-serif;
width: 100%;
height: 100%;
left: 0;
font-size: 1.8rem;
content: "+";
transform: rotate(-45deg);
border-radius: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #595959;
text-indent: 1px;
}
.close:hover:after {
background: var(--clr);
color: #fff;
}
.toast-item.success {
animation-delay: 2s;
}
.toast-item.warning {
animation-delay: 1s;
}
.toast-item.error {
animation-delay: 0s;
}
.toast.help {
--bg: var(--ch1);
--clr: var(--ch2);
--brd: var(--ch3);
}
.icon-help:after {
content: "?";
}
.toast.success {
--bg: var(--cs1);
--clr: var(--cs2);
--brd: var(--cs3);
}
.icon-success:after {
content: "L";
font-size: 1.5rem;
font-weight: bold;
padding-bottom: 0.35rem;
transform: rotateY(180deg) rotate(-38deg);
text-indent: 0.1rem;
}
.toast.warning {
--bg: var(--cw1);
--clr: var(--cw2);
--brd: var(--cw3);
}
.icon-warning:after {
content: "!";
font-weight: bold;
}
.toast.error {
--bg: var(--ce1);
--clr: var(--ce2);
--brd: var(--ce3);
}
.icon-error:after {
content: "+";
font-size: 2.85rem;
line-height: 1.2rem;
transform: rotate(45deg);
}
.toast a {
color: var(--clr);
}
.toast a:hover {
color: var(--bg);
}
.toast-icons {
background: #fff;
padding: 1rem 1rem 1.25rem 1rem;
display: flex;
justify-content: space-around;
border-radius: 1rem;
gap: 1.5rem;
width: 100%;
box-sizing: border-box;
margin-top: 1rem;
margin-bottom: 1rem;
position: relative;
border: 0.15rem solid #fff1;
box-shadow: 0 0 1.5rem 0 #1a1f4340;
}
.toast-icons:before {
position: absolute;
width: calc(100% + 0.3rem);
height: calc(100% + 0.25rem);
--bg-help: 45%;
--bg-success: 45%;
--bg-warning: 45%;
--bg-error: 45%;
--bsc: #fff0;
background:
radial-gradient(circle at 14% var(--bg-help), var(--ch1), #fff0 1.5rem), radial-gradient(circle at 38% var(--bg-success), var(--cs1), #fff0 1.5rem), radial-gradient(circle at 62% var(--bg-warning), var(--cw1), #fff0 1.5rem), radial-gradient(circle at 86% var(--bg-error), var(--ce1), #fff0 1.5rem);
content: "";
bottom: -0.15rem;
border-radius: 1rem;
z-index: 0;
transition: --bg-help 0.5s ease 0s, --bg-success 0.5s ease 0s, --bg-warning 0.5s ease 0s, --bg-error 0.5s ease 0s, --bsc 0.5s ease 0s;
box-shadow: 0 0 1.5rem 0 #1a1f4320;
}
.toast-icons:has(label[for=t-help]:hover):before {
--bg-help: 53%;
--bsc: var(--ch2);
}
.toast-icons:has(label[for=t-success]:hover):before {
--bg-success: 53%;
--bsc: var(--cs2);
}
.toast-icons:has(label[for=t-warning]:hover):before {
--bg-warning: 53%;
--bsc: var(--cw2);
}
.toast-icons:has(label[for=t-error]:hover):before {
--bg-error: 53%;
--bsc: var(--ce2);
}
.toast-icon {
width: 3.5rem;
height: 3.5rem;
border-radius: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
cursor: pointer;
position: relative;
background: radial-gradient(circle at 50% 50%, var(--clr) 1.25rem, var(--brd) calc(1.25rem + 1px) 100%);
}
.toast-icon:after {
font-size: 1.75rem;
}
.icon-success:after {
font-size: 1.5rem;
padding-bottom: 0.25rem;
}
.icon-error:after {
font-size: 2.85rem;
line-height: 2rem;
font-weight: 500;
padding-top: 0.25rem;
max-height: 2rem;
}
.icon-help,
.toast-item.help {
--clr: #0070e0;
--brd: #0070e040;
}
.icon-success,
.toast-item.success {
--clr: #03a65a;
--brd: #03a65a40;
}
.icon-warning,
.toast-item.warning {
--clr: #fc8621;
--brd: #fc862140;
}
.icon-error,
.toast-item.error {
--clr: #db3056;
--brd: #db305640;
}
#t-help:checked ~ .toast-panel .toast-item.help,
#t-success:checked ~ .toast-panel .toast-item.success,
#t-warning:checked ~ .toast-panel .toast-item.warning,
#t-error:checked ~ .toast-panel .toast-item.error {
max-height: 0;
opacity: 0;
}
input[type=checkbox] {
display: none;
}
CSSCustomization and Interaction: To enhance user interaction, we apply specific styles to each type of toast, distinguishing them through color and iconography. Users can toggle the visibility of individual toasts by checking or unchecking the corresponding checkboxes. Furthermore, we implement hover effects on the toast icons and close buttons to provide visual feedback and improve usability.
Integration of Google Fonts: To elevate typography within our neumorphic toasts, we integrate the ‘Varela Round’ font from Google Fonts. This font enhances readability and adds a touch of elegance to the toast messages, enhancing the overall user experience.
Conclusion: In this tutorial, we’ve demonstrated how to create interactive neumorphic toasts using HTML and CSS. By combining innovative design principles with user-centric functionality, we’ve crafted a visually stunning and intuitive notification system. As you delve deeper into web development, may this tutorial inspire you to explore new avenues of creativity and enhance user engagement through immersive user interfaces.
Happy Coding!