{"id":879,"date":"2020-09-14T01:40:50","date_gmt":"2020-09-14T01:40:50","guid":{"rendered":"https:\/\/www.antpace.com\/blog\/?p=879"},"modified":"2025-08-25T17:44:44","modified_gmt":"2025-08-25T17:44:44","slug":"custom-ui-notifications","status":"publish","type":"post","link":"https:\/\/www.antpace.com\/blog\/custom-ui-notifications\/","title":{"rendered":"Custom UI notifications"},"content":{"rendered":"<p>Showing brief notifications to website visitors is an important UI\/UX component. They&#8217;re useful for providing feedback. They can communicate success, failure, or warnings.<\/p>\n<p>Don Norman (<a href=\"https:\/\/www.amazon.com\/gp\/product\/0465050654\/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0465050654&amp;linkCode=as2&amp;tag=antpace0a-20&amp;linkId=58c5e83d114c5e19ab287b87188917d7\" target=\"_blank\" rel=\"noopener\">The Design of Everyday Things<\/a>) mentions that &#8220;Feedback is essential, but not when it gets in the way of other things, including a calm and relaxing environment&#8221; and goes on to say &#8220;Feedback is essential, but it has to be done correctly&#8221;.<\/p>\n<p>A common use-case is data validation. Specifically, when logging in or signing up. If the user enters an invalid email address, or wrong login credentials, we need to let them know. The built in browser alert() is clunky and unsophisticated. Plugins are bloated and over-engineered. I wrote some basic HTML, CSS, and JavaScript that gets the job done and looks great.<\/p>\n<p>My code provides two versions of the alert. The first is a basic sticky bar that fades in and out at the top of the page.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-887 size-full\" src=\"https:\/\/www.antpace.com\/blog\/wp-content\/uploads\/2020\/10\/ui-alert.gif\" alt=\"example of alert message for an invalid email address\" width=\"600\" height=\"338\" \/><\/p>\n<p>The other flashes in the middle of the screen. I call it &#8220;in-your-face&#8221; alerts and reserve them for positive success messages.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-889\" src=\"https:\/\/www.antpace.com\/blog\/wp-content\/uploads\/2020\/10\/in-your-face-alert.gif\" alt=\"example of a flashing UI alert to provide positive feedback to users\" width=\"600\" height=\"338\" \/><\/p>\n<p>The CSS adds styles for both versions. Both utilize &#8216;position: fixed&#8217; to stay in a set location on the page. The &#8220;in-your-face&#8221; example uses a pulse animation to achieve its effect.<\/p>\n<pre>&lt;!-- UI-notifications.css --&gt;\n&lt;style&gt;\nbody{\n  margin: 0px;\n}\n.status-message{\n  display: none;\n  color: white;\n  text-align: center;\n  font-size: 16px;\n  padding: 8px;\n  border-top: 1px solid white;\n  border-bottom: 1px solid white;\n  position: fixed;\n  width: 100%;\n  top: 0px;\n  padding: 28px 8px;\n  background-color: #b12650;\n  z-index: 1000;\n}\n.status-message-inner{\n  margin: 0px;\n}\n\n.status-message-close{\n  cursor: pointer;\n  position: fixed;\n  right: 10px;\n}\n.in-your-face{\n  display: none;\n  position: fixed;\n  top: 45%;\n  width: 100%;\n  text-align: center;\n  font-size: 48px;\n  color: white;\n  z-index: 2;\n}\n.in-your-face-inner{\n    background: #005b96;\n    width: 80%;\n    margin: 0 auto;\n    opacity: .85;\n    padding: 10px;\n}\n@keyframes pulse{\n  50%  {transform: scale(1.2);}\n\n}\n.pulse{\n  animation: pulse 0.5s ease-in infinite;\n}\n&lt;\/style&gt;\n&lt;!-- end UI-notifications.css --&gt;\n<\/pre>\n<p>The javascript relies on jQuery as a dependency. It is written as a class, with a constructor and two methods. Each method takes message text as a parameter.<\/p>\n<pre>class UINotifications {\n\tconstructor() {\n\t\twindow.jQuery || document.write('&lt;script src=\"js\/vendor\/jquery-1.11.2.min.js\"&gt;&lt;\\\/script&gt;');\n\t\tvar statusMessageHtml = '&lt;div class=\"status-message\"&gt;&lt;p class=\"status-message-inner\"&gt;&lt;span class=\"status-message-text\"&gt;Welcome to My App&lt;\/span&gt;&lt;span class=\"status-message-close\"&gt;X&lt;\/span&gt;&lt;\/p&gt;&lt;\/div&gt;';\n\t\tvar inYourFaceHtml = '&lt;div class=\"in-your-face pulse\"&gt;&lt;p class=\"in-your-face-inner\"&gt;&lt;span class=\"in-your-face-text\"&gt;Great Job!&lt;\/span&gt;&lt;\/p&gt;&lt;\/div&gt;';\n\n\t\t$(document).on(\"click\", \".status-message-close\", function(){\n\t\t\t$(\".status-message\").fadeOut();\n\t\t});\n\n\t\tthis.statusMessage = $(\"&lt;div\/&gt;\").html(statusMessageHtml);\n\t\tthis.inYourFace = $(\"&lt;div\/&gt;\").html(inYourFaceHtml);\n\n\t\t$('body').prepend(this.inYourFace);\n\t\t$('body').prepend(this.statusMessage);\n\n\t}\n\n \tshowStatusMessage(message){\n \t\tvar notifications = this;\n\t  \tvar message = message || \"Default Message\"\n\t  \tvar statusMessageTimeout;\n\n\t\tif(notifications.statusMessage.find(\".status-message\").is(':visible')){\n\t     clearTimeout(statusMessageTimeout);\n\t    }\n\n\t\tnotifications.statusMessage.find(\".status-message .status-message-text\").html(message);\n\t\tnotifications.statusMessage.find(\".status-message\").fadeIn();\n\n\t    statusMessageTimeout = setTimeout(function(){\n\t       notifications.statusMessage.find(\".status-message\").fadeOut();\n\t    }, 5000)\n\n\t}\n\tshowInYourFace(message, callback){\n\t\tvar notifications = this;\n\t\tvar inYourFaceTimeout;\n\t\tvar inYourFaceRandoms = [\"Good work!\", \"Hard work!\", \"Nice job!\", \"Hustle!\"]\n\n\t\tvar message = message || inYourFaceRandoms[Math.floor(Math.random()*inYourFaceRandoms.length)];;\n\t\tvar callback = callback || function(){};\n\n\t\tif(notifications.inYourFace.find(\".in-your-face\").is(':visible')){\n\t     clearTimeout(inYourFaceTimeout);\n\t    }\n\n\t\tnotifications.inYourFace.find(\".in-your-face .in-your-face-text\").html(message);\n\t\tnotifications.inYourFace.find(\".in-your-face\").show();\n\n\t    inYourFaceTimeout = setTimeout(function(){\n\t       notifications.inYourFace.find(\".in-your-face\").fadeOut(function(){\n\t       \tcallback();\n\t       });\n\n\t    }, 1000)\n\t}\n}\n<\/pre>\n<p>This is a simple and lightweight solution to showing web app visitors informative alerts without using a plugin. Please, checkout the code and use it in your next project.<\/p>\n<p><a href=\"https:\/\/github.com\/pacea87\/ui-messages\" target=\"_blank\" rel=\"noopener\">You can find the code on GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Showing brief notifications to website visitors is an important UI\/UX component. They&#8217;re useful for providing feedback. They can communicate success, failure, or warnings. Don Norman (The Design of Everyday Things) mentions that &#8220;Feedback is essential, but not when it gets in the way of other things, including a calm and relaxing environment&#8221; and goes on &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.antpace.com\/blog\/custom-ui-notifications\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Custom UI notifications&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":3205,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,5],"tags":[33,66,71,133,134,135],"class_list":["post-879","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-design","category-web-development","tag-css","tag-html","tag-javascript","tag-ui","tag-uiux","tag-ux"],"_links":{"self":[{"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/posts\/879","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/comments?post=879"}],"version-history":[{"count":1,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/posts\/879\/revisions"}],"predecessor-version":[{"id":3206,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/posts\/879\/revisions\/3206"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/media\/3205"}],"wp:attachment":[{"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/media?parent=879"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/categories?post=879"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/tags?post=879"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}