Ryepower
Ryepower

Reputation: 181

how to tell an element to change its position once it expands outside the viewport?

I have a few nice description boxes attached to all buttons see picture number 0. enter image description here When I change the viewport size the description box just expands outside the viewport. See in the first pictureenter image description here

Obviously, it is because I set the position of all my absolutely positioned description boxes the same(top:-25px right:-79px) and when a user hovers over the button on the very right it expands too far. I could change the one being on the very right but it wouldn't solve anything as I don'T know how many of these pictures will be added when the website is done.

So I want to use javascript to change the position of any description box that expands outside the viewport so that it looks like the one in the second picture.enter image description here

The code I use for this setup is here:

<div id="grid-container" class="container">
  <div id="product1" class="products">
    <input id="one" type="checkbox" name="wobblers" value="one">

    <label for="one">
                            <img id="one" src="https://cdn.shopify.com/s/files/1/1557/0907/products/product-image-507865262.jpg?v=1527268422"
                                alt="rapala">
                            <button id="product1-info" class="btn btn-info">info
                                <div class="info-box" id="info-box1"></div>
                            </button>
                        </label>
  </div>
</div>

CSS:

img {
  width: 75px;
}

.info-box {
  display: none;
  width: 80px;
  height: 60px;
  background: grey;
  position: absolute;
  top: -25px;
  right: -79px;
  border-radius: 10% 10% 10% 1%;
}

#product1-info:hover #info-box1 {
  display: block;
}

.products {
  display: inline-block;
}

label {
  position: relative;
  display: inline-block;
  vertical-align: middle;
}

#grid-container {
  display: flex;
  justify-content: space-around;
  flex-wrap: wrap;
}

Thank you!

Upvotes: 1

Views: 491

Answers (2)

Ryepower
Ryepower

Reputation: 181

Here is the final solution:

Javascript:

const hovered = document.querySelectorAll('.product-info');
Array.prototype.forEach.call(hovered, function (item) {
    item.addEventListener("mouseover", changeElementPosition);
  });

function changeElementPosition() {
    const tooltipParent = document.querySelectorAll(".product-info");
    const tooltip = document.querySelectorAll('.info-box');
    for (let i = 0; i < tooltipParent.length; i++) {
        console.log(tooltip[i]);
        const tooltipParentRightPosition = tooltipParent[i].getBoundingClientRect().right;
        const windowWidth = document.documentElement.clientWidth;
        const tooltipInitPosition = -tooltip[i].getBoundingClientRect().width;
        if ((tooltipParentRightPosition - windowWidth) >= tooltipInitPosition) {
            tooltip[i].style.right = tooltipParentRightPosition - windowWidth + 'px';
        }
    else{
        tooltip[i].style.right = "-80px"; 
    }
    }


    window.addEventListener("resize", () => {
        const tooltipParent = document.querySelectorAll(".product-info");
        const tooltip = document.querySelectorAll('.info-box');
        for (let i = 0; i < tooltipParent.length; i++) {
            const tooltipParentRightPosition = tooltipParent[i].getBoundingClientRect().right;
            const windowWidth = document.documentElement.clientWidth;
            const tooltipInitPosition = -tooltip[i].getBoundingClientRect().width;
            if ((tooltipParentRightPosition - windowWidth) >= tooltipInitPosition) {
                tooltip[i].style.right = tooltipParentRightPosition - windowWidth + 'px';
            }
    else{
        tooltip[i].style.right = "-80px"; 
    }
        }
    });
}

CSS:

  .btn-wrapper {
    display: inline-block;
    position: relative;
  }
  .info-box{
    visibility: hidden;
    width:80px;
    height:60px;
    background:grey;
    position:absolute;
    top: -60px;
    right: -80px;
    border-radius:10% 10% 10% 1%;
  }
  .product-info:hover .info-box {
    visibility: visible;
  }

Html:

            <div id="product4" class="products">
                <input id="four" type="checkbox" name="wobblers" value="four">
                <label for="four">
                    <img id="four" src="https://cdn.shopify.com/s/files/1/1557/0907/products/product-image-507865262.jpg?v=1527268422" alt="rapala">
                    <div class="btn-wrapper">
                        <button id="product4-info" class="product-info btn btn-info">info
                            <div class="info-box" id="info-box4"></div>
                        </button>
                    </div>
                </label>
            </div>

Upvotes: 1

Mila Lysenko
Mila Lysenko

Reputation: 104

function changeElementPosition() {
    const tooltipParent = document.getElementById('product1-info');
    const tooltip = document.getElementById('info-box1');
    const tooltipParentRightPosition = tooltipParent.getBoundingClientRect().right;
    const windowWidth = document.documentElement.clientWidth;
    const tooltipInitPosition = -tooltip.getBoundingClientRect().width;

    if ((tooltipParentRightPosition - windowWidth) >= tooltipInitPosition) {
        tooltip.style.right = tooltipParentRightPosition - windowWidth + 'px';
    }

    window.addEventListener("resize", () => {
        const tooltipParent = document.getElementById('product1-info');
        const tooltip = document.getElementById('info-box1');
        const tooltipParentRightPosition = oltipParent.getBoundingClientRect().right;
        const windowWidth = document.documentElement.clientWidth;
        const tooltipInitPosition = -tooltip.getBoundingClientRect().width;

        if ((tooltipParentRightPosition - windowWidth) >= tooltipInitPosition) {
            tooltip.style.right = tooltipParentRightPosition - windowWidth + 'px';
        }
    });
}




<div id="grid-container" class="container">
    <div id="product1" class="products">
        <label for="one">
            <input id="one" type="checkbox" name="wobblers" value="one">
        </label>
        <img>
        <div class="btn-wrapper">
            <button id="product1-info" class="btn btn-info">info</button>
            <div class="info-box" id="info-box1"></div>
        </div>
    </div>
</div>

And several changes in CSS

.btn-wrapper {
    display: inline-block;
    position: relative;
}
.info-box {
    visibility: hidden;
    width: 80px;
    height: 60px;
    background: grey;
    position: absolute;
    top: -60px;
    right: -80px;
    border-radius: 10% 10% 10% 1%;
}

#product1-info:hover + #info-box1 {
    visibility: visible;
}

Hope it's help you)

Upvotes: 2

Related Questions