skip to Main Content

In the following HTML structure (parent > child > grandchild), the parent has the overflow:hidden; property

<div id="parent">
    <div id="child">        
        <div id="grandchild">
        </div>  
    </div>
</div>

Can the grandchild element override the parent’s overflow hidden?

My main concern are that

  • the grandchild’s position is related to the child’s position.
  • since the child’s position is related to the parent position, it has to move with the parent when scrolling.
  • the grandchild’s styles (font-size, font-family…) are inherited from the child.

The child must not be visible outside the parent, unlike the grandchild.

I already try many things. Nothing works and I start to wonder if what I want to do is possible.

In the following JSFiddle, the blue box should be half visible, but the green one should be fully visible.

https://jsfiddle.net/Imabot/qs0625Lr/13/

2

Answers


  1. UPDATE The only drawback is that it does not solution does not support scrolling

    In this update, we added a container to hold the children. We transform that container to the bottom of the parent, instead of using #child as the container. This snippet allows you to use your original code of transforms instead of using bottom.

    body {
    height: 1000px;
    }
    
    * {
        margin:0;
    }
    
    #parent {
        background: rgba(255, 0, 0, 0.5);   
        width: 200px;
        height: 100px;
    }
    
    .container {
      position: relative;
      transform: translateY(60px);
    }
    
    /* Must not be visible outside the parent */
    #child {
        background-color: blue;
        opacity: 0.4;
        width: 60px;
        height: 40px;
    }
    
    
    /* Must be visible outside the parent */
    #grandchild {
        position: absolute;
        background-color: green;
        opacity: 0.5;
        width: 60px;
        height: 60px;
        transform: translateX(100px);
    }
    <div id="parent">
      <div class="container">
        <div id="child">        
            <div id="grandchild">
            </div>  
        </div>
      </div>
    </div>

    Fixed code not scrolling

    With your current code, it does not seem possible. But if you changed your #child‘s code from transform: translateY(60px); to bottom: -60px and your #grandchild to position: fixed, the code functions as you intended.

    * {
        margin:0;
    }
    
    #parent {
        background: rgba(255, 0, 0, 0.5);   
        width: 200px;
        height: 100px;
      overflow: hidden;
    }
    
    /* Must not be visible outside the parent */
    #child {
        position: relative;
        background-color: blue;
        opacity: 0.4;
        width: 60px;
        height: 40px;
      bottom: -60px;
    }
    
    
    /* Must be visible outside the parent */
    #grandchild {
        position: fixed;
        background-color: green;
        opacity: 0.5;
        width: 60px;
        height: 60px;
        transform: translateX(100px);
        
    }
    <div id="parent">
        <div id="child">        
            <div id="grandchild">
            </div>  
        </div>
    </div>
    Login or Signup to reply.
  2. If sizes and offsets of the elements are known, can be used clip-path instead overflow: hidden.
    In the example below, entered something into css variables.

    * {
      margin: 0;
    }
    
    #parent {
      --child-width: 60px;
      --grandchild-translate-x: 100px;
      --bottom: -20px;
      background: rgba(255, 0, 0, 0.5);
      width: 200px;
      height: 100px;
      display: flex;
      align-items: flex-end;
      clip-path: polygon(
        0 0,
        100% 0,
        100% 100%,
        calc(var(--child-width) + var(--grandchild-translate-x)) 100%,
        calc(var(--child-width) + var(--grandchild-translate-x)) calc(100% - var(--bottom)),
        var(--grandchild-translate-x) calc(100% - var(--bottom)),
        var(--grandchild-translate-x) 100%,
        0 100%
       );
    }
    
    /* Must not be visible outside the parent */
    #child {
      background-color: blue;
      opacity: 0.4;
      width: var(--child-width);
      height: var(--child-width);
      margin-bottom: var(--bottom);
    }
    
    /* Must be visible outside the parent */
    #grandchild {
      background-color: green;
      opacity: 0.5;
      width: var(--child-width);
      height: var(--child-width);
      transform: translateX(var(--grandchild-translate-x));
    }
    <div id="parent">
        <div id="child">        
            <div id="grandchild">
            </div>  
        </div>
    </div>

    Or generate a clip-path using javascript, if each element is responsive:

    clip();
    $(window).on('resize', clip)
    
    function clip(){
        const grandchild = $('#grandchild');
        const right = grandchild.position().left + grandchild.width();
        const bottom = grandchild.position().top + grandchild.height();
        const left = grandchild.position().left;
        const clipPath = `polygon(
        0 0,
        100% 0,
        100% 100%,
        ${right}px 100%,
        ${right}px ${bottom}px,
        ${left}px ${bottom}px,
        ${left}px 100%,
        0 100%
       )`;
        $('#parent').css('clip-path', clipPath);
    }
    #parent {
      background: rgba(255, 0, 0, 0.5);   
      width: 200px;
      height: 100px;
      display: flex;
      align-items: flex-end;
      position: relative;
    }
    
    /* Must not be visible outside the parent */
    #child {
      background-color: blue;
      opacity: 0.4;
      width: 80px;
      height: 100px;
      margin-bottom: -40px;
    }
    
    
    /* Must be visible outside the parent */
    #grandchild {
      background-color: green;
      opacity: 0.5;
      width: 60px;
      height: 80px;
      transform: translate(100px, 40px);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="parent">
       <div id="child">        
          <div id="grandchild">
          </div>  
       </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search