Click here to Skip to main content
15,887,027 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I'm working on a chat box UI, and I'm having trouble making it responsive for smaller screens. I want the chat section to be responsive, meaning that it should automatically adjust its layout to fit the screen size. The main goal is to ensure that users, on smaller screens, don't have to scroll horizontally to access various elements like the Send button, mainly the horizontal scroll.
Here's the code:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" 
integrity="sha512-MV7K8+y+gLIBoVD59lQIYicR65iaqukzvf/nwasF0nqhPay5w/9lJmVM2hMDcnK1OnMGCdVK+iQrJ7lzPJQd1w==" 
crossorigin="anonymous" referrerpolicy="no-referrer" />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/boxicons@latest/css/boxicons.min.css">
    <title>Chat Box</title>
</head>
<style>
*{
  margin: 0;
  padding: 0;
}
:root {
  --body-bg: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  --msger-bg: #fff;
  --border: 2px solid #ddd;
  --left-msg-bg: #ececec;
  --right-msg-bg: #579ffb;
}

.mncht,
.mncht:before,
.mncht:after{
  margin: 0;
  padding: 0;
  box-sizing: inherit;
}
.mncht{
    box-sizing: border-box;
   margin: 5px auto;
   height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 5px;
  background-image: var(--body-bg);
  font-family: Helvetica, sans-serif;
}
.msger {
  display: flex;
  flex-flow: column wrap;
  justify-content: space-between;
  width: 100%;
  max-width: 867px;
  margin: 25px 10px;
  height: calc(100% - 50px);
  border: var(--border);
  border-radius: 5px;
  background: var(--msger-bg);
  box-shadow: 0 15px 15px -5px rgba(0, 0, 0, 0.2);
}

.msger-header {
  display: flex;
  justify-content: space-between;
  padding: 10px;
  border-bottom: var(--border);
  background: #eee;
  color: #666;
}
.msger-header-title{
  margin: 2px;
  padding: 5px;
}
.nofs{
  margin: 2px;
}
.msger-chat {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
}
.msger-chat::-webkit-scrollbar {
  width: 6px;
}
.msger-chat::-webkit-scrollbar-track {
  background: #ddd;
}
.msger-chat::-webkit-scrollbar-thumb {
  background: #bdbdbd;
}
.msg {
  display: flex;
  align-items: flex-end;
  margin-bottom: 10px;
}
.msg:last-of-type {
  margin: 0;
}
.msg-img {
  width: 50px;
  height: 50px;
  margin-right: 10px;
  background: #ddd;
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  border-radius: 50%;
}
.msg-bubble {
  max-width: 450px;
  padding: 14px;
  border-radius: 14px;
  background: var(--left-msg-bg);
}
.msg-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 9px;
}
.msg-info-name {
  font-size: 0.89em;
  margin-right: 10px;
  font-weight: bold;
}
.msg-info-time {
  font-size: 0.75em;
}
.msg-text{
  word-wrap: break-word;
  font-size: 0.81em;
}
.left-msg .msg-bubble {
  border-bottom-left-radius: 0;
}
.msg-bubble {
    width: 55%;
}
.right-msg {
  flex-direction: row-reverse;
}
.right-msg .msg-bubble {
  background: var(--right-msg-bg);
  color: #fff;
  border-bottom-right-radius: 0;
}
.right-msg .msg-img {
  margin: 0 0 0 10px;
}

.msger-inputarea {
  width: 100%;
  display: flex;
  padding: 10px;
  border-top: var(--border);
  background: #eee;
}
.msger-inputarea * {
  padding: 2px;
  border: none;
  border-radius: 3px;
  font-size: 0.91em;
}
.msger-input {
  padding: 20px;
  flex-grow: 1;
  margin: 10px auto;
  background: #ddd;
}
.msger-send-btn {
  border-radius: 8px;
  padding: 8px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  margin-left: 3px;
  color: #000000;
  font-weight: bold;
  cursor: pointer;
  font-size: 23.4px;

  transition: background 0.23s;
}
.msger-send-btn:hover {
  background-color: #0e8859;
}

.msger-send-btn-mg {
    margin-left: -7px !important;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    padding: 15px !important;
    margin: 13px 2.8px auto;
    font-size: 23px;
    height: 77%;
    width: 8%;
    color: #000000;
    border-radius: 7px;
    cursor: pointer;
    transition: background-color 0.3s ease;
    position: relative;
    overflow: hidden;
}
.msger-send-btn-mg:hover{
  background-color: #0e8859;
}
.msger-send-btn-mg i {
    margin-right: 2px;
}

.msger-send-btn-mg input {
    position: absolute;
    top: 0;
    left: 0;
    width: 10%;
    height: 80%;
    opacity: 0;
    cursor: pointer;
}

.msger-send-btn-mg:hover {
    background-color: #0e8859;
}

.error {
    color: red;
    margin-top: 10px;
}

.hidden {
    display: none;
}

.snd-btn{
  margin-right: -8px;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}
.ext-cr{
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 12px;
  border-radius: 8px;
  width: 100%;
  font-size: 21px;
  cursor: pointer;
}
.ext-cr:hover{
  background:#52a4c5;
}
.ext-cr:focus{
  background:#36768f;
}
.msger-chat {
  background-color: #fcfcfe;
  /* background-image:  */
}

@media only screen and (max-width: 420px) {
  .msger-send-btn-mg{
    margin-left: -6px;
    width: 12%;
    padding: 12px !important;
    font-size: 21px;
  }
  .msger-send-btn{
    font-size: 22px;
  }
}
</style>
<body>
    <div class="mncht">
    <section class="msger">
        <header class="msger-header">
          <div class="msger-header-title">
            <i class="fas fa-comment-alt nofs"></i>&nbsp; &nbsp; Chat Kura
          </div>
          <div class="msger-header-options">
            <span class="ext-cr" id="open-modal"><i class="fa-regular fa-circle-xmark"></i></span>
          </div>
        </header>
      
        <main class="msger-chat">
          <div class="msg left-msg">
            <div
             class="msg-img"
             style="background-image: url(https://image.flaticon.com/icons/svg/327/327779.svg)"
            ></div>
      
            <div class="msg-bubble">
              <div class="msg-info">
                <div class="msg-info-name">Your name</div>
                <div class="msg-info-time">Message Time</div>
              </div>
      
              <div class="msg-text">
                You can change your name in JS section!
              </div>
            </div>
          </div>
      
          <div class="msg right-msg">
            <div
             class="msg-img"
             style="background-image: url(https://image.flaticon.com/icons/svg/145/145867.svg)"
            ></div>
      
            <div class="msg-bubble">
              <div class="msg-info">
                <div class="msg-info-name">Your Name</div>
                <div class="msg-info-time">Message Time </div>
              </div>
      
              <div class="msg-text">
                You can change your name in JS section!
              </div>
            </div>
          </div>
        </main>
      
        <form class="msger-inputarea">
            <button class="msger-send-btn-mg">
        <i class="far fa-images" id="thfn"></i>
        <input type="file" id="imageInput" accept="image/*" onchange="validateImage()">
    </button>
    <p id="errorText" class="error hidden">
      File size exceeds the limit (2MB).</p>
          <input type="text" class="msger-input" 
          placeholder="Enter your message...">
          <div class="snd-btn">
          <button type="submit" class="msger-send-btn">
          <i class="fas fa-paper-plane"> </i> &nbsp;
          </button> </div>
        </form>
      </section>
    </div>
    
    <script>
const msgerForm = get(".msger-inputarea");
const msgerInput = get(".msger-input");
const msgerChat = get(".msger-chat");

const BOT_MSGS = [
  "Hi, how are you?",
  "Ohh... I can't understand what you trying to say. Sorry!",
  "I like to play games... But I don't know how to play!",
  "Sorry if my answers are not relevant. :))",
  "I feel sleepy! :("
];

// Icons made by Freepik from www.flaticon.com
const BOT_IMG = "https://image.flaticon.com/icons/svg/327/327779.svg";
const PERSON_IMG = "https://image.flaticon.com/icons/svg/145/145867.svg";
const BOT_NAME = "BOT";
const PERSON_NAME = "Sajad";

msgerForm.addEventListener("submit", event => {
  event.preventDefault();

  const msgText = msgerInput.value;
  if (!msgText) return;

  appendMessage(PERSON_NAME, PERSON_IMG, "right", msgText);
  msgerInput.value = "";

  botResponse();
});

function appendMessage(name, img, side, text) {
  //   Simple solution for small apps
  const msgHTML = `
    <div class="msg ${side}-msg">
      <div class="msg-img" style="background-image: url(${img})"></div>

      <div class="msg-bubble">
        <div class="msg-info">
          <div class="msg-info-name">${name}</div>
          <div class="msg-info-time">${formatDate(new Date())}</div>
        </div>

        <div class="msg-text">${text}</div>
      </div>
    </div>
  `;

  msgerChat.insertAdjacentHTML("beforeend", msgHTML);
  msgerChat.scrollTop += 500;
}

function botResponse() {
  const r = random(0, BOT_MSGS.length - 1);
  const msgText = BOT_MSGS[r];
  const delay = msgText.split(" ").length * 100;

  setTimeout(() => {
    appendMessage(BOT_NAME, BOT_IMG, "left", msgText);
  }, delay);
}

// Utils
function get(selector, root = document) {
  return root.querySelector(selector);
}

function formatDate(date) {
  const h = "0" + date.getHours();
  const m = "0" + date.getMinutes();

  return `${h.slice(-2)}:${m.slice(-2)}`;
}

function random(min, max) {
  return Math.floor(Math.random() * (max - min) + min);
}
 
    </script>
<script>
    function validateImage() {
            const fileInput = document.getElementById("imageInput");
            const errorText = document.getElementById("errorText");
            const maxSize = 2 * 1024 * 1024; // 2MB

            if (fileInput.files.length > 0) {
                const fileSize = fileInput.files[0].size;
                if (fileSize > maxSize) {
                    errorText.style.display = "block";
                } else {
                    errorText.style.display = "none";
                }
            }
        }
</script>
<script src="main.js"></script>
</body>
</html>


What I have tried:

I've attempted to add some media queries to adjust the layout in CSS, but it's not achieving the level of responsiveness.

CSS
@media only screen and (max-width: 420px) {
  .msger-send-btn-mg{
    margin-left: -6px;
    width: 12%;
    padding: 12px !important;
    font-size: 21px;
  }
  .msger-send-btn{
    font-size: 22px;
  }
}

Thank you for your help! ;)
Posted
Updated 12-Oct-23 9:41am
v3
Comments
[no name] 12-Oct-23 14:25pm    
You design for the smallest - you then get to think about what's important (left, top or ?). Then let the "fluid" design expand based on available screen real estate and "expandable controls" (grid; listbox, wrapping panels; expanders; drop downs; text wrapping / truncating).
Member 15627495 13-Oct-23 2:44am    
as you need responsive, forget 'px' with { top / left / height / width }.
" % " is a good auto one.

1 solution

Easiest would be to use float for your chat box, when a user have to scroll left to right the chat box still "floats above the current screen to access it easily - Floating Chatbox[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900