DigitalJedi
DigitalJedi

Reputation: 1651

Child Visibility Affects Parent Visibility

I'm having a weird issue when setting a child container to visibility: visible via JavaScript in the $(document).ready function.

Here's the problem:

I'm having a parent element, that has bootstraps helperclass class="d-none". I now want to set the CSS of the child of this element to visibility: visible. The problem is that, as long as the $(document).ready function is running, the parent and its child are visible.

This means that some weird stuff is going on, since wrapping a visible element in a hidden element should always show nothing. But apparently it does show both the parent and the child.

Does anybody know how to fix this?

TO BE SPECIFIC HERE:

  1. I want to call the $(document).ready function
  2. I don't want to see the child, nor the parent when calling the function, as this following code does also not show the child nor the parent because the parent has "d-none"

.parent{
  width: 100px;
  height: 100px;
}

.child{
  width: 50px;
  height: 50px;
  visibility: visible;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  <div class="parent d-none">
    <div calss="child">
  </div>
</div>

Why can the parent be seen in the below snippet, when setting the visibility of the child via js?

The parent should still have "d-none", and therefore all its children should also not be visible, or what am I understanding wrong here?

To reproduce this issue, copy the lower code snippet to your answer and hit run a few times, you will see the yellow and red rectangles show up for a short amount of time, before they are actually not visible anymore.

$(document).ready(function() {
    $(".visi").css("visibility", "visible");
});
.d-none {
  background-color: red;
  width: 100px;
  height: 100px;
}

.visi {
  background-color: yellow;
  width: 50px;
  height: 50px;
}
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<div class="d-none">
  <div class="visi" style="visibility: visible;"></div>
</div>

Upvotes: 1

Views: 430

Answers (2)

zer00ne
zer00ne

Reputation: 43910

Let me start out by saying that I probably do not understand 100% of what you are trying explain. This is what I have gathered please inform me of any differences:

  1. Your while loop was an attempt to reveal the divs at a future time.

    • loops are way too fast to be any use as a timer you need setTimeout()
    • JavaScript is asynchronous so if you plan to reveal one div and then the next (I'm guessing here because you weren't really specific), you'll get one possibly finishing before another or possibly way later. You can make times synchronous by using async function and await keyword.
      • asynchronous: A set to start at 2secs and B set to start at 2.5secs they'll both end possibly at the same time.
      • synchronous: A starts at 2secs and ends B stars 2.5secs later.
  2. You right to assume that a child is is hidden if the parent is hidden except if the parent has visibility:hidden and a child has visibility: visible the parent will remain hidden and the child will be visible.

  3. Bootstrap class .d-none is entirely different. It is display:none; which practically removes the element from all but HTML. With visibility:hidden the element still takes space. An element with display:none doesn't take up space.

function reveal(selector) {
  $(selector).css('visibility', 'visible')
}

const selectors = ['.child', '.parent'];
const times = [3000, 5500];

async function sync(selectors, times) {
  const showChild = () => {
    return new Promise(resolve => {
      setTimeout(() => resolve(reveal(selectors[0])), times[0]);
    });
  }

  const showParent = () => {
    return new Promise(resolve => {
      setTimeout(() => resolve(reveal(selectors[1])), times[1]);
    });
  }

  await showChild();
  await showParent();
}

sync(selectors, times);
.parent {
  visibility: hidden;
  background-color: red;
  width: 100px;
  height: 100px;
}

.child {
  visibility: hidden;
  background-color: yellow;
  width: 50px;
  height: 50px;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous">

<div class="parent">
  <div class="child"></div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

Upvotes: 1

Sina
Sina

Reputation: 270

Check this code. I fixed some parts.

function myFunction(){

      if (1 === 1) {
        $(".visi").css("visibility", "visible");
        var i = 0;
        while(i < 100){
          console.log(i++);
        }
      } 

    }
 
.visi {
  background-color: yellow;
  width: 50px;
  height: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="d-none">

  <div class="visi" style="visibility: hidden;" ></div>
 


</div>
<button onclick="myFunction()">Click me</button>

you can set the visibility to hidden at the beginning and then set it to visible

Upvotes: 0

Related Questions