Search code examples
javascripthtmlcss

Why does button move with float property?


im trying to make a VN, and i tried to make a float because i need the text to go in between the two images, but i think its causing the button to move slightly to the right side when it appears. I keep seeing recommendations for other methods of putting things on the right, like display:flex; but I cant seem to use it in this instance.

document.addEventListener("DOMContentLoaded", () => {
  let index = 1;
  const button = document.querySelector('button');
  const sections = document.querySelectorAll('section');
  button.addEventListener('click', function() {
    if (sections[index]) {
      if (hasImg(index) && hasImg(index - 1)) {
        sections[index - 1].classList.remove("d-block");
      }
      sections[index].classList.add("d-block");
      typeWriter(sections[index]);
    }
    if (!sections[++index]) {
      button.disabled = true;
    }
  });

  function hasImg(index) {
    return sections[index].querySelector('img');
  }

  typeWriter(sections[0]);
});

function typeWriter(el) {
  const content = el.innerHTML;
  el.innerHTML = '';
  let i = 0;
  const typeInterval = setInterval(() => {
    if (content[i] === '<' && content[i + 1] === 'i' && content[i + 2] === 'm' && content[i + 3] === 'g') {
      let endIdx = content.indexOf('>', i) + 1;
      el.innerHTML += content.substring(i, endIdx);
      i = endIdx;
    } else {
      el.innerHTML += content[i];
      i++;
    }
    if (i >= content.length) {
      clearInterval(typeInterval);
    }
  }, 95);
}
section {
  display: none;
  text-align: center;
}

.d-block {
  display: block;
}

button {
  margin: 0 auto;
  display: block;
}

.portrait {
  animation: fadeIn 5s;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

.happy {
  float: left;
}

.sad {
  float: right;
}
<section class="text d-block">First</section>
<section class="text">Second</section>
<section class="text">
  <img class="portrait happy" src="https://cdn.iconscout.com/icon/premium/png-256-thumb/arrow-small-right-4241483-3517873.png">
  <img class="portrait sad" src="https://cdn.iconscout.com/icon/free/png-256/free-small-diamond-geometric-blue-38006.png">
</section>
<section>Las</section>
<section>Ursa</section>
<button>next</button>


Solution

  • I would recommend avoiding using float: left and float: right because they give your elements a height of 0, which makes it impossible to prevent elements from jumping during dynamic adding.

    You can use display: flex and also specify the sizes of your images to prevent sections from jumping during image partial load.

    This can be achieved like so:

    document.addEventListener("DOMContentLoaded", () => {
      let index = 1;
      const button = document.querySelector('button');
      const sections = document.querySelectorAll('section');
      button.addEventListener('click', function() {
        if (sections[index]) {
          if (hasImg(index) && hasImg(index - 1)) {
            sections[index - 1].classList.remove("d-block");
          }
          sections[index].classList.add("d-block");
          typeWriter(sections[index]);
        }
        if (!sections[++index]) {
          button.disabled = true;
        }
      });
    
      function hasImg(index) {
        return sections[index].querySelector('img');
      }
    
      typeWriter(sections[0]);
    });
    
    function typeWriter(el) {
      el = el.querySelector('span') ? el.querySelector('span') : el;
      const content = el.innerHTML;
      el.innerHTML = '';
      let i = 0;
      const typeInterval = setInterval(() => {
        if (content.substring(i, i + 4) === '<img' || content.substring(i, i + 5) === '<span') {
          let endIdx = content.indexOf('>', i) + 1;
          el.innerHTML += content.substring(i, endIdx);
          i = endIdx;
        } else {
          el.innerHTML += content[i];
          i++;
        }
        if (i >= content.length) {
          clearInterval(typeInterval);
        }
      }, 95);
    }
    section {
      display: none;
      text-align: center;
    }
    
    section span {
      align-self: center;
    }
    
    .d-block {
      display: flex;
      justify-content: space-between;
    }
    
    button {
      margin: 0 auto;
      display: block;
    }
    
    .portrait {
      animation: fadeIn 5s;
    }
    
    @keyframes fadeIn {
      0% {
        opacity: 0;
      }
      100% {
        opacity: 1;
      }
    }
    
    .happy {
      float: left;
    }
    
    .sad {
      float: right;
    }
    
    .text {
      justify-content: center;
    }
    <html>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <section class="text d-block">First</section>
    <section class="text">Second</section>
    <section>
      <img class="portrait happy" src="https://cdn.iconscout.com/icon/premium/png-256-thumb/arrow-small-right-4241483-3517873.png" width="256" height="256">
      <span>Some text is here</span>
      <img class="portrait sad" src="https://cdn.iconscout.com/icon/free/png-256/free-small-diamond-geometric-blue-38006.png" width="256" height="256">
    </section>
    <section class="text">Las</section>
    <section class="text">Ursa</section>
    <button>next</button>
    
    </html>

    Please let me know if this helps.