Возможно ли разрешенное дочернее div?

Конечный результат

Изображение является дедушкой grandparent div, черным полупрозрачным наложением является родительский div, а обрезанная часть - дочерний div. Пользователь увидит изображение бабушки и родительского наложения, затем он может обрезать его, используя дочерний обрезщик div. Я пробовал и проваливался с opacity и фоном rgba .

Эти сумасшедшие подходы действительно работают для меня -

  1. Установите изображение бабушки и дедушки на фоне дочернего div, а затем измените x / y background-position .
  2. Объедините ребенка и родителя в один отдельный div и используйте border rgba в качестве наложения (предложение моего друга).
  3. Обнаружено это в stackoverflow, который использует box-shadow вместо границ и похоже на аналогичный подход к # 2.

Моя незначительная проблема с # 2 и № 3 заключается в том, что мне нужно добавить еще один div для пунктирных границ, чтобы пользователь четко знал, что он обрезает. Но моя большая проблема со всеми из них заключается в том, что ни один из них не выглядит как правильный подход.

Есть ли правильный / лучший / 2018-йэш / «это настолько очевидный, вы идиот» способ сделать это?

Обновление: вот базовая разметка (я тоже с другой разметкой, если это помогает в ее решении)

 #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; } #parentOverlay { background: rgba(0,0,0,0.5); height: 100%; position: relative; } #childCropper { border: 1px dashed #ccc; left: 50px; height: 100px; width: 100px; position: absolute; top: 50px; } 
 <div id="grandparentImage"> <div id="parentOverlay"> <div id="childCropper"></div> </div> </div> 

Всего 5 ответов


Вы можете установить коробку-тень с 100vmax распространения 100vmax на #childCropper . Таким образом, он всегда будет охватывать экран:

 #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> 


Это кажется идеальной работой для псевдоэлементов. Таким образом, это решение является обновлением предложения №2 в вопросе, но вместо использования самого элемента он использует :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> 

Примечание. Элемент #parentOverlay больше не понадобится. Также для этого решения требуется, чтобы элемент grand-parent имел overflow: hidden свойство и z-index ( почему? ).


Я предполагаю, что это то, что вы ищете:

 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> 

Это простая форма, следующая за полигоном темной области. Позиция точек может быть выражена в процентах, используя calc() или даже предоставляя пользовательский <svg> по id (и используя внешний инструмент, например Adobe Illustrator, для его создания.

Текущее покрытие браузера: 87,99% .

У вас может быть любой контент под маской. И вместо того, чтобы использовать position:fixed , вы можете использовать position:absolute и поместить его в желаемый контейнер с position:relative , чтобы применить к этому контейнеру.


Другой метод - использовать <svg> s <path> . Анимация их довольно прямолинейна, используя либо анимацию smil, либо простые ключевые кадры CSS.

Пример:

 #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> 


Overlaying divs (Доказательство концепции)

 .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> 


Вот еще один подход, который использует только один элемент, где вы можете полагаться на градиент и несколько фона для создания обрезанного наложения, а также пунктирной границы:

 #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> 

Оверлей будет образован четырьмя градиентами в виде прямоугольных форм, и каждая граница будет повторяющимся градиентом, чтобы чередовать белый / прозрачный.

Трудная часть состоит в том, чтобы понять разные значения и как выполняется капиляция background-size / background-position . Вот хорошее чтение для этого: background-position не работает в процентах для линейного градиента


Мы также можем и точки вашего скриншота:

 #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; } , #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> 


Есть идеи?

10000