Search code examples
javascripthtmlcssresponsive-designviewport

Change button color based on screen size


What I am trying to achieve is when my device size is less than 736 px, the button should animate. I got the button working correctly, however, I’m struggling to work with the specific screen size.

$(window).resize(function() {
  if ($(window).width() <= 736) {
    // do something
    
    let myBtn = document.querySelector(".btn");
    let btnStatus = false;

    myBtn.style.background = "#FF7F00";

    function bgChange() {
      if (btnStatus == false) {
        myBtn.style.background = "#FF0000";
        btnStatus = true;
      }
      else if (btnStatus == true) {
        myBtn.style.background = "#FF7F00";
        btnStatus = false;
      }
    }

    myBtn.onclick = bgChange;
  }
});
.btn {
  width: 200px;
  height: 100px;
  text-align: center;
  padding: 40px;
  text-decoration: none;
  font-size: 20px;
  letter-spacing: .6px;
  border-radius: 5px;
  border: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button class="btn">CLICK ME</button>


Solution

  • Here's an implementation of what you're trying to do that uses:

    1. class to alter button styling instead of style,
    2. vanilla JavaScript instead of jQuery.

    Using class is a good idea, as it keeps the styling in the CSS and out of the JavaScript code.

    Using vanilla JavaScript whenever you can is preferable.

    Here are the two new classes:

    .btn-small-screen {
      background: #FF7F00;
    }
    
    .btn-clicked {
      background: #FF0000;
    }
    

    .btn-small-screen class is applied when the window is small, .btn-clicked is toggled whenever the button is clicked.

    Here's the JavaScript code:

    let myBtn = document.querySelector('.btn');
    let isSmallWindow = () => window.innerWidth <= 736;
    
    function toggleButtonOnClick () {
      myBtn.classList.toggle('btn-clicked');
    }
    
    function setButtonMode () {
      if (isSmallWindow()) {
        myBtn.classList.add('btn-small-screen');
        myBtn.addEventListener('click', toggleButtonOnClick);
      } else  {
        myBtn.classList.remove('btn-small-screen');
        myBtn.classList.remove('btn-clicked');
        myBtn.removeEventListener('click', toggleButtonOnClick);
      }
    }
    
    // setup mode on resize
    window.addEventListener('resize', setButtonMode);
    
    // setup mode at load
    window.addEventListener('load', setButtonMode);
    

    References:

    A working example:

    let myBtn = document.querySelector('.btn');
    let isSmallWindow = () => window.innerWidth <= 736;
    
    function toggleButtonOnClick () {
      myBtn.classList.toggle('btn-clicked');
    }
    
    function setButtonMode () {
      if (isSmallWindow()) {
        myBtn.classList.add('btn-small-screen');
        myBtn.addEventListener('click', toggleButtonOnClick);
      } else  {
        myBtn.classList.remove('btn-small-screen');
        myBtn.classList.remove('btn-clicked');
        myBtn.removeEventListener('click', toggleButtonOnClick);
      }
    }
    
    // setup small mode on resize
    window.addEventListener('resize', setButtonMode);
    
    // setup small mode at load
    window.addEventListener('load', setButtonMode);
        .btn {
          width: 200px;
          height: 100px;
          text-align: center;
          padding: 40px;
          text-decoration: none;
          font-size: 20px;
          letter-spacing: .6px;
          border-radius: 5px;
          border: none;
        }
    
        .btn-small-screen {
          background: #FF7F00;
        }
    
        .btn-clicked {
          background: #FF0000;
        }
    <button class="btn">CLICK ME</button>

    Note: There is one optimization that I left out, so the code would be easier to follow.

    Notice that setButtonMode() changes the DOM every time, even though it might already be set to the desired mode. This is inefficient.

    To improve efficiency and only change the DOM when necessary, you could introduce a state variable (call it smallMode), and set it true whenever appropriate. Like so:

    let smallMode = false;
    
    function setButtonMode () {
      if (isSmallWindow()) {
        if (!smallMode) {
          myBtn.classList.add('btn-small-screen');
          myBtn.addEventListener('click', toggleButtonOnClick);
          smallMode = true;
        }
      } else if (smallMode)  {
        myBtn.classList.remove('btn-small-screen');
        myBtn.classList.remove('btn-clicked');
        myBtn.removeEventListener('click', toggleButtonOnClick);
        smallMode = false;
      }
    }