DEV Community

Cover image for Twitter Tweet Box with Character Limit Highlighting in HTML CSS & JavaScript
CodingNepal
CodingNepal

Posted on

Twitter Tweet Box with Character Limit Highlighting in HTML CSS & JavaScript

Hey friends, today in this blog you'll learn how to create a Twitter Tweet Box with Character Limit Highlighting using HTML CSS & JavaScript. In the earlier blog, I have shared how to Easily Limit Input Characters in JavaScript, and in this blog, you'll also learn to limit input characters but it will be more advanced than the previous one because in this Twitter tweet box there is a feature of character limit highlighting which was not in the previous project.

If you have a Twitter account then you definitely know what is tweet box and how it looks like. In this project [Twitter Post Share Box or Tweet Box], on the webpage, there is a tweet box as you can see in the preview image. In this box, there is a typing area, some media icons, a characters limit counter, and a tweet button. At first, the counter will be hidden and the tweet button also disabled but once you start typing then there is visible the counter and the button also active/clickable.

In this tweet box, there is a limit of 100 characters which means you can type 1-100 length/numbers of characters. Once you crossed the limit then the over characters will start highlighting, the tweet button is again disabled and the counter color is also charged into red and it shows you how many characters that you have to remove to tweet or proceed.

Video Tutorial of Tweet Box with Character Limit Highlighting

Click here to Watch Full Video on YouTube

You can copy the codes from the given boxes or download the code files from the given link but I recommend you download the source code files instead of copying codes. Click here to download code files.

HTML CODE:
<!DOCTYPE html>
<!-- Created By CodingNepal - www.codingnepalweb.com -->
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Twitter Tweet Box UI Design | CodingNepal</title>
  <link rel="stylesheet" href="style.css">
  <link rel="stylesheet" href="https://unicons.iconscout.com/release/v3.0.6/css/line.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"/>
</head>
<body>
  <div class="wrapper">
    <div class="input-box">
      <div class="tweet-area">
        <span class="placeholder">What's happening?</span>
        <div class="input editable" contenteditable="true" spellcheck="false"></div>
        <div class="input readonly" contenteditable="true" spellcheck="false"></div>
      </div>
      <div class="privacy">
        <i class="fas fa-globe-asia"></i>
        <span>Everyone can reply</span>
      </div>
    </div>
    <div class="bottom">
      <ul class="icons">
        <li><i class="uil uil-capture"></i></li>
        <li><i class="far fa-file-image"></i></li>
        <li><i class="fas fa-map-marker-alt"></i></li>
        <li><i class="far fa-grin"></i></li>
        <li><i class="far fa-user"></i></li>
      </ul>
      <div class="content">
        <span class="counter">100</span>
        <button>Tweet</button>
      </div>
    </div>
  </div>

  <script src="script.js"></script>

</body>
</html>
Enter fullscreen mode Exit fullscreen mode
CSS CODE
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap');
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Open Sans', sans-serif;
}
body{
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: #1da1f2;
}
::selection{
  color: #fff;
  background: #1da1f2;
}
.wrapper{
  background: #fff;
  max-width: 475px;
  width: 100%;
  border-radius: 15px;
  padding: 25px 25px 15px 25px;
  box-shadow: 0px 10px 15px rgba(0,0,0,0.1);
}
.input-box{
  padding-top: 10px;
  border-bottom: 1px solid #e6e6e6;
}
.input-box .tweet-area{
  position: relative;
  min-height: 130px;
  max-height: 170px;
  overflow-y: auto;
}
.tweet-area::-webkit-scrollbar{
  width: 0px;
}
.tweet-area .placeholder{
  position: absolute;
  margin-top: -3px;
  font-size: 22px;
  color: #98A5B1;
  pointer-events: none;
}
.tweet-area .input{
  outline: none;
  font-size: 17px;
  min-height: inherit;
  word-wrap: break-word;
  word-break: break-all;
}
.tweet-area .editable{
  position: relative;
  z-index: 5;
}
.tweet-area .readonly{
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
  color: transparent;
  background: transparent;
}
.readonly .highlight{
  background: #fd9bb0;
}
.input-box .privacy{
  color: #1da1f2;
  margin: 15px 0;
  display: inline-flex;
  align-items: center;
  padding: 7px 10px;
  border-radius: 50px;
  cursor: pointer;
  transition: background 0.2s ease;
}
.privacy:hover, .icons li:hover{
  background: #e7f5fe;
}
.privacy i{
  font-size: 18px;
}
.privacy span{
  font-size: 15px;
  font-weight: 600;
  margin-left: 7px;
}
.bottom{
  display: flex;
  margin-top: 13px;
  align-items: center;
  justify-content: space-between;
}
.bottom .icons{
  display: inline-flex;
}
.icons li{
  list-style: none;
  color: #1da1f2;
  font-size: 20px;
  margin: 0 2px;
  height: 38px;
  width: 38px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: background 0.2s ease;
}
.bottom .content{
  display: flex;
  align-items: center;
  justify-content: center;
}
.bottom .counter{
  color: #333;
  display: none;
  font-weight: 500;
  margin-right: 15px;
  padding-right: 15px;
  border-right: 1px solid #aab8c2;
}
.bottom button{
  padding: 9px 18px;
  border: none;
  outline: none;
  border-radius: 50px;
  font-size: 16px;
  font-weight: 700;
  background: #1da1f2;
  color: #fff;
  cursor: pointer;
  opacity: 0.5;
  pointer-events: none;
  transition: background 0.2s ease;
}
.bottom button.active{
  opacity: 1;
  pointer-events: auto;
}
.bottom button:hover{
  background: #0d8bd9;
}
Enter fullscreen mode Exit fullscreen mode
JavaScript CODE
const wrapper = document.querySelector(".wrapper"),
editableInput = wrapper.querySelector(".editable"),
readonlyInput = wrapper.querySelector(".readonly"),
placeholder = wrapper.querySelector(".placeholder"),
counter = wrapper.querySelector(".counter"),
button = wrapper.querySelector("button");

editableInput.onfocus = ()=>{
  placeholder.style.color = "#c5ccd3";
}
editableInput.onblur = ()=>{
  placeholder.style.color = "#98a5b1";
}

editableInput.onkeyup = (e)=>{
  let element = e.target;
  validated(element);
}
editableInput.onkeypress = (e)=>{
  let element = e.target;
  validated(element);
  placeholder.style.display = "none";
}

function validated(element){
  let text;
  let maxLength = 100;
  let currentlength = element.innerText.length;

  if(currentlength <= 0){
    placeholder.style.display = "block";
    counter.style.display = "none";
    button.classList.remove("active");
  }else{
    placeholder.style.display = "none";
    counter.style.display = "block";
    button.classList.add("active");
  }

  counter.innerText = maxLength - currentlength;

  if(currentlength > maxLength){
    let overText = element.innerText.substr(maxLength); //extracting over texts
    overText = `<span class="highlight">${overText}</span>`; //creating new span and passing over texts
    text = element.innerText.substr(0, maxLength) + overText; //passing overText value in textTag variable
    readonlyInput.style.zIndex = "1";
    counter.style.color = "#e0245e";
    button.classList.remove("active");
  }else{
    readonlyInput.style.zIndex = "-1";
    counter.style.color = "#333";
  }
  readonlyInput.innerHTML = text; //replacing innerHTML of readonly div with textTag value
}
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
growkon21 profile image
Growkon

Great tutorial! I appreciate how you broke down each step, making it easy to follow. The explanation of form validation is especially helpful, as it ensures user inputs are correct before submission. I am a student of Best International Schools in Bangalore. Would love to see more examples like this for other types of elements. Keep up the good work!