<div class="msgbox-message-container">
  <h1>Responsive Message Box</h1>
  <h3>Using Native Javascript class</h3>
  <p><button id="msgboxPersistent" class="msgbox-message-button" type="button">Show persistent</button></p>
  <p><button id="msgboxShowMessage" class="msgbox-message-button" type="button">Show non-persistent</button></p>
  <p><button id="msgboxHiddenClose" class="msgbox-message-button" type="button">Hidden close button</button></p>
</div>
@import url("https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700");

/*****************************/
/* MESSAGE BOX RELATED CLASS */
/*          (START)          */
/*****************************/

$msgbox-area-width-l: 480px;

$msgbox-area-y-pos: 15px;
$msgbox-area-x-s: 20px;
$msgbox-area-x-m: 80px;
$msgbox-area-x-l: 15px;

$msgbox-box-color: #ffffff;
$msgbox-box-background-color: rgba(#000000, 0.7);
$msgbox-box-padding: 1.5rem;
$msgbox-box-margin: 1rem;
$msgbox-box-border-radius: 12px;
$msgbox-box-box-shadow: 0 10px 15px rgba(#000000, 0.65);
$msgbox-box-backdrop-filter: blur(4px);
$msgbox-box-transition-time: 256ms;

$msgbox-close-color: #ffffff;
$msgbox-close-margin: 10px;
$msgbox-close-transition-time: 64ms;

$msgbox-close-hover-color: #efefef;
$msgbox-close-hover-text-shadow: 0 0 4px #ffffff;

.msgbox-area {
  font-size: inherit;
  max-height: 100%;
  position: fixed;
  bottom: $msgbox-area-y-pos;
  left: $msgbox-area-x-s;
  right: $msgbox-area-x-s;
}

.msgbox-box {
  font-size: inherit;
  color: $msgbox-box-color;
  background-color: $msgbox-box-background-color;
  margin: 0 0 $msgbox-box-margin;
  display: flex;
  flex-direction: column;
  position: relative;
  border-radius: $msgbox-box-border-radius;
  box-shadow: $msgbox-box-box-shadow;
  backdrop-filter: $msgbox-box-backdrop-filter;
  transition: opacity $msgbox-box-transition-time ease-in;
  &.msgbox-box-hide {
    opacity: 0;
  }
  &:last-child {
    margin: 0;
  }
}

.msgbox-content {
  font-size: inherit;
  padding: $msgbox-box-padding;
  padding-bottom: $msgbox-box-padding / 2;
  flex-shrink: 1;
}

.msgbox-command {
  padding: $msgbox-box-padding;
  padding-top: $msgbox-box-padding / 2;
  display: flex;
}

.msgbox-close {
  color: $msgbox-close-color;
  font-size: inherit;
  text-decoration: none;
  margin: 0 $msgbox-close-margin;
  flex-grow: 0;
  flex-shrink: 0;
  position: relative;
  transition:
    color $msgbox-close-transition-time ease-out,
    text-shadow $msgbox-close-transition-time ease-out;
  &:hover {
    color: $msgbox-close-hover-color;
    text-shadow: $msgbox-close-hover-text-shadow;
  }
  &:first-child {
    margin-left: auto;
  }
  &:last-child {
    margin-right: 0;
  }
}

@media (min-width: 481px) and (max-width: 767px) {
  .msgbox-area {
    left: $msgbox-area-x-m;
    right: $msgbox-area-x-m;
  }
}

@media (min-width: 768px) {
  .msgbox-area {
    width: $msgbox-area-width-l;
    height: 0;
    top: $msgbox-area-y-pos;
    left: auto;
    right: $msgbox-area-x-l;
  }
}

/*****************************/
/* MESSAGE BOX RELATED CLASS */
/*           (END)           */
/*****************************/

$button-color: #387cdc;

body {
  font-family: "Open Sans", sans-serif;
  font-size: 16px;
  background-color: #e4e4e4;
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.msgbox-area {
  font-size: 16px;
}

.msgbox-message-container {
  text-align: center;
  background-color: #ffffff;
  padding: 2rem;
  box-sizing: border-box;
  border-radius: 1rem;
  box-shadow: 0 0.3rem 0.5rem rgba(#000000, 0.5);
  h1, h3 {
    font-weight: normal;
    padding: 0.5rem 1rem;
    margin: 0;
    &:first-child {
      padding-top: 0;
    }
    &:last-child {
      padding-bottom: 0;
    }
  }
  p {
    padding: 0.5rem 1rem;
    margin: 0;
    &:first-child {
      padding-top: 0;
    }
    &:last-child {
      padding-bottom: 0;
    }
  }
}

.msgbox-message-button {
  font-size: 18px;
  font-family: inherit;
  color: white;
  background-color: $button-color;
  width: 250px;
  border: solid 2px darken($button-color, 10%);
  padding: 0.75rem 1.5rem;
  cursor: pointer;
  outline: none;
  box-shadow: 0 0.4rem darken($button-color, 10%);
  transition:
    background-color 64ms ease-out,
    box-shadow 64ms ease-out,
    transform 64ms ease-out;
  &:hover,
  &:focus,
  &:active {
    background-color: lighten($button-color, 5%);
  }
  &:active {
    background-color: darken($button-color, 5%);
    box-shadow: 0 0 darken($button-color, 10%);
    transform: translateY(0.4rem);
  }
}
View Compiled
class MessageBox {
  constructor(option) {
    this.option = option;
    
    this.msgBoxArea = document.querySelector("#msgbox-area");
    
    if (this.msgBoxArea === null) {
      this.msgBoxArea = document.createElement("DIV");
      this.msgBoxArea.setAttribute("id", "msgbox-area");
      this.msgBoxArea.classList.add("msgbox-area");
      
      document.body.appendChild(this.msgBoxArea);
    }
  }
  
  show(msg, callback, closeLabel) {
    if (msg === "" || msg === undefined || msg === null) {
      // If the 'msg' parameter is not set, throw an error
      
      throw "Message is empty or not defined.";
    }
    
    if (closeLabel === undefined || closeLabel === null) {
      // Of the close label is undefined, or if it is null
      
      closeLabel = "Close";
    }
    
    const option = this.option;

    const msgboxBox = document.createElement("DIV");
    const msgboxContent = document.createElement("DIV");
    const msgboxCommand = document.createElement("DIV");
    const msgboxClose = document.createElement("A");
    
    // Content area of the message box
    msgboxContent.classList.add("msgbox-content");
    msgboxContent.innerText = msg;
    
    // Command box or the button container
    msgboxCommand.classList.add("msgbox-command");
    
    // Close button of the message box
    msgboxClose.classList.add("msgbox-close");
    msgboxClose.setAttribute("href", "#");
    msgboxClose.innerText = closeLabel;
    
    // Container of the Message Box element
    msgboxBox.classList.add("msgbox-box");
    msgboxBox.appendChild(msgboxContent);

    if (option.hideCloseButton === false
        || option.hideCloseButton === undefined) {
      // If the hideCloseButton flag is false, or if it is undefined
      
      // Append the close button to the container
      msgboxCommand.appendChild(msgboxClose);
      msgboxBox.appendChild(msgboxCommand);
    }

    this.msgBoxArea.appendChild(msgboxBox);
    
    msgboxClose.onclick = (evt) => {
      evt.preventDefault();
      
      if (msgboxBox.classList.contains("msgbox-box-hide")) {
        return;
      }
      
      clearTimeout(this.msgboxTimeout);
      
      this.msgboxTimeout = null;

      this.hide(msgboxBox, callback);
    };

    if (option.closeTime > 0) {
      this.msgboxTimeout = setTimeout(() => {
        this.hide(msgboxBox, callback);
      }, option.closeTime);
    }
  }
  
  hideMessageBox(msgboxBox) {
    return new Promise(resolve => {
      msgboxBox.ontransitionend = () => {
        resolve();
      };
    });
  }
  
  async hide(msgboxBox, callback) {
    if (msgboxBox !== null) {
      // If the Message Box is not yet closed
      
      msgboxBox.classList.add("msgbox-box-hide");
    }
    
    await this.hideMessageBox(msgboxBox);
    
    this.msgBoxArea.removeChild(msgboxBox);

    clearTimeout(this.msgboxTimeout);
    
    if (typeof callback === "function") {
      // If the callback parameter is a function

      callback();
    }
  }
}

const msgboxShowMessage = document.querySelector("#msgboxShowMessage");
const msgboxHiddenClose = document.querySelector("#msgboxHiddenClose");

// Creation of Message Box class, and the sample usage
const msgbox = new MessageBox({
  closeTime: 10000,
  hideCloseButton: false
});
const msgboxPersistent = new MessageBox({
  closeTime: 0
});
const msgboxNoClose = new MessageBox({
  closeTime: 5000,
  hideCloseButton: true
});

document.querySelector("#msgboxPersistent").addEventListener("click", () => {
  msgboxPersistent.show("Hello! I am a persistent message box! I will hide myself if you close me.");
});

msgboxShowMessage.addEventListener("click", () => {
  msgbox.show("Hello! I am a non-persistent message box! I will hide myself automatically after 5 seconds, but you may also close me.", null);
});

msgboxHiddenClose.addEventListener("click", () => {
  msgboxNoClose.show("Hello! My close button is hidden, but I will close myself after 5 seconds.");
});

// Show the message at the beginning
msgboxPersistent.show(
  "Hello! I am a message box! I will appear on the page load period. I also have a callback. You may check on 'Console' to see.",
  () => {
    console.log("I am the callback! Of course, you may add various javaScript codes to make the callback function colourful.");
  },
  "Has callback"
);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.