Is a see-through child div possible?

后端 未结 5 2030
遥遥无期
遥遥无期 2020-12-03 21:45

The image is the grandparent div, the black translucent overlay is the parent div, and the cropped section is the child div. User will see the grandparent image and

相关标签:
5条回答
  • 2020-12-03 22:10

    You can set box-shadow with 100vmax spread radius on the #childCropper. In this way it will always cover the screen:

    #grandparentImage {
      background: url(https://9to5mac.com/wp-content/uploads/sites/6/2018/07/Desert-2.jpg) no-repeat;
      background-size: cover;
      position: relative;
      height: 500px;
    }
    
    #childCropper {
      position: absolute;  
      top: 50px;
      left: 50px;
      height: 200px;
      width: 200px;
      border: 1px dashed #ccc;
      box-shadow: 0 0 0 100vmax rgba(0,0,0,0.5);
    }
    
    body {
      margin: 0;
    }
    <div id="grandparentImage">
      <div id="childCropper"></div>
    </div>

    0 讨论(0)
  • 2020-12-03 22:13

    Here is another approach that uses only one element where you can rely on gradient and multiple background to create the cropped overlay and also the dotted border:

    #grandparentImage {
      --g:linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5));
      --t:repeating-linear-gradient(to right ,#ccc 0,#ccc 2px,transparent 2px, transparent 4px);
      --b:repeating-linear-gradient(to bottom,#ccc 0,#ccc 2px,transparent 2px, transparent 4px);
      background-image: 
        /*the border*/ 
        var(--t),var(--t),var(--b),var(--b),
        /*the overlay*/
        var(--g),var(--g),var(--g),var(--g),
        /*the image*/
        url(https://picsum.photos/1000/800?image=1069);
      background-size: 
        /*the border*/ 
        40% 2px,40% 2px,2px 40%,2px 40%,
        /*the overlay*/
        100% 30%,100% 30%,20% 40%, 40% 40%,
        /*the image*/
        cover;
      background-position:
        /*the border*/ 
        33.33% 30%,left 33.33% bottom 30%,20% 50%,60% 50%,
        /*the overlay*/
        top,bottom,left center,right center,
        /*the image*/
        center;
      background-repeat:no-repeat;
      position: relative;
      height: 100vh;
    }
    
    body {
     margin:0;
    }
    <div id="grandparentImage">
    
    </div>

    The overlay will be formed by 4 gradients as a rectangular shapes and each border will be a repeating gradient to alternate white/transparent.

    The hard part is to understand the different values and how the caclulation of background-size/background-position is done. Here is a good reading for this: background-position not working in percentage for linear-gradient


    We can also and the dots of your screenshot:

    #grandparentImage {
      --g:linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5));
      --t:repeating-linear-gradient(to right ,#ccc 0,#ccc 2px,transparent 2px, transparent 4px);
      --b:repeating-linear-gradient(to bottom,#ccc 0,#ccc 2px,transparent 2px, transparent 4px);
      --d:radial-gradient(#ccc 60%,transparent 62%);
      background-image: 
        /*the dots*/
        var(--d),var(--d),var(--d),var(--d),var(--d),var(--d),var(--d),var(--d),
        /*the border*/ 
        var(--t),var(--t),var(--b),var(--b),
        /*the overlay*/
        var(--g),var(--g),var(--g),var(--g),
        /*the image*/
        url(https://picsum.photos/1000/800?image=1069);
      background-size: 
        /*the dots*/
        10px 10px,10px 10px,10px 10px,10px 10px,10px 10px,10px 10px,10px 10px,10px 10px,
        /*the border*/ 
        40% 2px,40% 2px,2px 40%,2px 40%,
        /*the overlay*/
        100% 30%,100% 30%,20% 40%, 40% 40%,
        /*the image*/
        cover;
      background-position:
        /*the dots*/
        20% 30%,20% 70%,20% 50%,60% 30%,60% 50%,60% 70%,40% 30%,40% 70%, 
        /*the border*/ 
        33.33% 30%,left 33.33% bottom 30%,20% 50%,60% 50%,
        /*the overlay*/
        top,bottom,left center,right center,
        /*the image*/
        center;
      background-repeat:no-repeat;
      position: relative;
      height: 100vh;
    }
    
    body {
     margin:0;
    }
    <div id="grandparentImage">
    
    </div>

    0 讨论(0)
  • 2020-12-03 22:14

    This seems like a perfect job for pseudo-elements. So this solution is an upgrade of #2 suggestion in the question, but instead of using the element itself, it uses :after:

    #grandparentImage {
      background: url(https://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/%D0%94%D0%B7%D0%B5%D0%BC%D0%B1%D1%80%D0%BE%D0%BD%D1%8F._%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D0%BB%D1%83%D1%87%D0%B8_%D1%81%D0%BE%D0%BB%D0%BD%D1%86%D0%B0.jpg/800px-%D0%94%D0%B7%D0%B5%D0%BC%D0%B1%D1%80%D0%BE%D0%BD%D1%8F._%D0%9F%D0%B5%D1%80%D0%B2%D1%8B%D0%B5_%D0%BB%D1%83%D1%87%D0%B8_%D1%81%D0%BE%D0%BB%D0%BD%D1%86%D0%B0.jpg) no-repeat;
      background-size: cover;
      position: relative;
      height: 500px;
      overflow: hidden;
      z-index: 1;
    }
    
    #childCropper {
      border: 2px dashed #ccc;
      position: absolute;
      top: 50px;
      left: 50px;
      height: 200px;
      width: 200px;
    }
    
    #childCropper:after {
      content: "";
      width: 100%;
      height: 100%;
      border: 1000px solid rgba(0, 0, 0, 0.5);
      position: absolute;
      top: -1000px;
      left: -1000px;
      z-index: -1;
    }
    <div id="grandparentImage">
      <div id="childCropper"></div>
    </div>

    Note: There will be no need for the #parentOverlay element anymore. Also this solution requires the grand-parent element to have an overflow: hidden property and a z-index (why?).

    0 讨论(0)
  • 2020-12-03 22:14

    I'm guessing this is what you're looking for:

    overlay-mask {
      background-color: rgba(0,0,0,.65);
      clip-path: polygon(0% 0%, 75% 0%, 75% 25%, 25% 25%, 25% 75%, 75% 75%, 75% 0%, 100% 0%, 100% 100%, 0 100%);
      z-index: 1;
      pointer-events: none;
      /* rest is optional, you could use 
       * `position:absolute` to place it in a parent with `relative` 
       */
      position: fixed;
      top: 0; bottom: 0; left: 0; right: 0;
    }
    
    body {
      margin: 0;
      background: url("https://loremflickr.com/800/600") no-repeat center center /cover;
      min-height: 100vh;
    }
    <overlay-mask></overlay-mask>

    It's a simple shape following the polygon of the dark area. Points position can be expressed in percentage, using calc() or even providing a custom <svg> by id (and use an external tool, like Adobe Illustrator to generate it.

    Current browser coverage: 87.99%.

    You can have any content under the mask. And, instead of using position:fixed, you could use position:absolute and place it in the desired container with position:relative, to apply to that container.


    Another method is to use <svg>s <path>. Animating them is pretty straight forward using either smil animations or plain CSS keyframes.

    Example:

    #overlay-mask {
      z-index: 1;
      pointer-events: none;
      /* rest is optional, you could use 
       * `position:absolute` to place it in a parent with `relative` 
       */
      position: fixed;
      top: 0; bottom: 0; left: 0; right: 0;
      color: rgba(0,0,0,.65);
      width: calc(100% + 4px);
      height: calc(100% + 4px);
      left: -2px;
      top: -2px;
    }
    
    body {
      margin: 0;
      background: url("https://loremflickr.com/800/600") no-repeat center center /cover;
      min-height: 200vh;
    }
    h2 {color: white;}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    <svg id="overlay-mask" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
         preserveAspectRatio="none"
         viewBox="0 0 600 600" width="600" height="600">
        <defs>
            <path d="M0 600L0 0L600 0L600 600L0 600ZM100 200L200 200L200 100L100 100L100 200Z" id="cutPath">
            <animate attributeType="XML" attributeName="d" 
            values="M0 600L0 0L600 0L600 600L0 600ZM100 200L200 200L200 100L100 100L100 200Z; M0 600L0 0L600 0L600 600L0 600ZM200 300L300 300L300 200L200 200L200 200Z;M0 600L0 0L600 0L600 600L0 600ZM100 300L300 300L300 100L100 100L100 200Z;M0 600L0 0L600 0L600 600L0 600ZM100 200L200 200L200 100L100 100L100 100Z"
            keyTimes="0; 0.33; 0.66; 1"
            dur="3s" repeatCount="indefinite"
            />
            </path>
        </defs>
        <use xlink:href="#cutPath" opacity="1" fill="currentColor" fill-opacity="1"></use>
        <use xlink:href="#cutPath" opacity="1" fill="none" stroke="white" stroke-width="2"
        stroke-dasharray="1,1"
        ></use>
    </svg>
    
    <h2>Scroll down...</h2>

    0 讨论(0)
  • 2020-12-03 22:15

    Overlaying divs (Proof of Concept)

    .parent,
    .child {
      background-image: url(https://scontent-lht6-1.cdninstagram.com/vp/0f18c710d8dc3ebd48819b3f9f44b5cc/5C28EE7E/t51.2885-15/e35/29094825_1798384780455300_8914767740305145856_n.jpg?se=7&ig_cache_key=MTc0MDQ5MzIwMjE5OTYyODM5MQ%3D%3D.2);
      background-size: contain;
    }
    
    .parent {
      height: 1072px;
      width: 1072px;
      opacity: 0.3
    }
    
    .child {
      position: absolute;
      top: 150px;
      left: 20px;
      height: 200px;
      width:500px;
      background-position: -20px -150px; 
      background-size: 1072px 1072px
    }
    <div class="parent"></div>
    <div class="child"></div>

    0 讨论(0)
提交回复
热议问题