Подтвердить что ты не робот

Скрыть переполнение за уложенным div с прозрачным фоном на верхней части тела с фоном SVG

У меня есть макет, содержащий fixed div (#navigation) с кнопками. В макет также входит прокручиваемый контент (.card).

#navigation в настоящее время имеет зеленый фон для демонстрационных целей. Например:

#navigation {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translate(-50%, 0%);
  background: green;
  padding: 25px;
}
<div id="navigation"><button id="btn1">Button</button>
  <button id="btn2">Button</button>
  <button id="btn3">Button</button>
  <button id="btn4">Button</button>
</div>
4b9b3361

Ответ 1

Попробуйте установить одинаковый фон для #navigation также с той же фоновой позицией (см. пример ниже)

#card-wrapper {
  width: 250px;
  margin: 100px auto;
}

.card {
  height: 200px;
  width: 200px;
  background: #131418;
  margin: 1em auto;
  display: inline-block
}

#navigation {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1;
  padding: 40px 25px 25px 25px;
  background: #ffffff url(http://svgur.com/i/42T.svg);
  background-attachment: fixed;
  background-size: cover;
  background-position: 0 0;
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
  background: #ffffff url(http://svgur.com/i/42T.svg);
  background-attachment: fixed;
  background-size: cover;
  background-position: 0 0;
}
<div id="main">

  <div id="navigation">
    <button id="btn1">Button</button>
    <button id="btn2">Button</button>
    <button id="btn3">Button</button>
    <button id="btn4">Button</button>
  </div>

  <div id="card-wrapper">
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
  </div>

</div>

Ответ 2

Решение JavaScript

Дух решения:

Tested on CH62, FF57 and IE11

В то время как ответ kastriotcunaku хорош, если вы не против форматирования, Это решение поддерживает те же параметры, что и данные, здесь я попытаюсь дать #navigation фон, который выглядит и позиционируется как тело, чтобы придать иллюзию прозрачности с помощью JavaScript, чтобы сделать его отзывчивым.

Background-size:cover на div #navigation сделает его более плотным. Поэтому я попытаюсь эмулировать cover, растягивая фон, чтобы покрыть все тело и все еще отображаться только в элементе навигации:

navigationElement.style.backgroundSize=(document.body.clientHeight/imgH)*imgW+"px";

/* imgW image width, imgH original image height. A trick to maintain the width/height ratio of the SVG. You can programmatically get size of the image
  For some reason I've needed that even on the body for IE11 who doesn't seem to handle "cover" properly */

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

    n=document.getElementById('navigation');    
    var isChrome = !!window.chrome && !!window.chrome.webstore;
    var isIE = /*@[email protected]*/false || !!document.documentMode;
    var imgH=647.7;
    var imgW= 2351.2;

       function resizeHandler(){ 
            r=n.getBoundingClientRect();
            n.style.backgroundSize=(innerHeight/imgH)*imgW+"px";
            if (isChrome){
                n.style.backgroundPosition=r.width/2+"px 0px"
            } else if (isIE){
                n.style.backgroundPosition=0
        document.body.style.backgroundSize=(innerHeight/imgH)*imgW+"px";
            } else{
                n.style.backgroundPosition=-r.x+"px -20px"
            }
       }    
       addEventListener("resize",resizeHandler);
       document.addEventListener ("DOMContentLoaded",resizeHandler);
       
       
#card-wrapper {
  width: 250px;
  margin: 100px auto;
}

.card {
  height: 200px;
  width: 200px;
  background: #131418;
  margin: 1em auto;
  display: inline-block
}

#navigation {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translate(-50%, 0%);
  z-index: 1;
  padding: 25px;
  border: 0.1px dotted;     
  background: #ffffff url(http://svgur.com/i/42T.svg);
  background-attachment: fixed;
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
  background:#ffffff  url(http://svgur.com/i/42T.svg);
  background-attachment:fixed;
  background-size:cover;
  background-position:0;
}
<div id="main">

  <div id="navigation">
    <button id="btn1">Button</button>
    <button id="btn2">Button</button>
    <button id="btn3">Button</button>
    <button id="btn4">Button</button>
  </div>

  <div id="card-wrapper">
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
  </div>

</div>

Ответ 3

Я действительно, действительно, действительно хотел найти решение, используя некоторые новые функции CSS, такие как clip или backdrop-filter. В конце концов, я нашел решение, но он определенно подходит к концу и не так элегантен, как решение kastriotcunaku.

В приведенном ниже решении используется экспериментальное свойство backdrop-filter, чтобы содержимое, содержащее элемент #screen, имело opacity(0). К сожалению, есть и минусы:

  • Требуется несколько строк JavaScript для установки размеров элемента #screen в соответствии с элементом #navigation - этого можно было бы избежать, если бы ширина/высота/позиция элемента #screen были заранее известны
  • Будет работать только в браузерах, поддерживающих свойство backdrop-filter - в основном Safari, или в Chrome с включенным флагом функций Experimental Web Platform (который вы можете установить, перейдя в chrome://flags/# enable-experimental-web- платформенные функции в Chrome)

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

введите описание изображения здесь

Если вы используете браузер с поддержкой backdrop-filter, вы можете просмотреть его в действии ниже:

var screen = document.getElementById("screen");
var navigation = document.getElementById("navigation");
var navigationStyle = window.getComputedStyle(navigation, null);

screen.style.height = navigationStyle.getPropertyValue('height');
screen.style.width = navigationStyle.getPropertyValue('width');
screen.style.border = navigationStyle.getPropertyValue('border');
screen.style.borderColor = "transparent";
#card-wrapper {
  width: 250px;
  margin: 100px auto;
}

.card {
  height: 200px;
  width: 200px;
  background: #131418;
  margin: 1em auto;
  display: inline-block
}

#screen,
#navigation {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translate(-50%, 0%);
  padding: 25px;
}

#screen {
  backdrop-filter: opacity(0%);
  -webkit-backdrop-filter: opacity(0%);
}

#navigation {
  z-index: 10;
  border: 1px solid;
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
}

.bkg {
  position: fixed;
  z-index: 10;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: url(http://svgur.com/i/42T.svg);
  background-attachment:fixed;
  background-size:cover;
  
}
<div id="main">

  <div id="screen"></div>
  
  <div class="bkg"></div>
  
  <div id="navigation">
    <button id="btn1" onclick="alert()">Button</button>
    <button id="btn2">Button</button>
    <button id="btn3">Button</button>
    <button id="btn4">Button</button>
  </div>

  <div id="card-wrapper">
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
  </div>
  

</div>

Ответ 4

Вы можете использовать навигацию в качестве фиксированной навигации и разрешать только прокрутку к своей области содержимого. Для этого вам нужно добавить position: absolute; в #card-wrapper и удалить display:inline-block из .card.

#card-wrapper {
  position: absolute;
  top: 100px;
  bottom: 0;
  left: 0;
  right: 0;
  overflow: auto;
}

.card {
  height: 200px;
  width: 200px;
  background: #131418;
  margin: 1em auto;
  clear:both;
}

#navigation {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translate(-50%, 0%);
  z-index: 1;
  padding: 25px;
  border: 1px solid;
  background: transparent
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
  background: url(http://svgur.com/i/42T.svg);
  background-attachment:fixed;
  background-size:cover;
}
<div id="main">

  <div id="navigation"><button id="btn1">Button</button>
    <button id="btn2">Button</button>
    <button id="btn3">Button</button>
    <button id="btn4">Button</button>
  </div>

  <div id="card-wrapper">
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
  </div>

</div>

Ответ 5

После небольшого количества проб и ошибок у меня есть это решение, которое я считаю лучшим до сих пор

#card-wrapper {
  width: 250px;
  margin: 100px auto;
}

.card {
  height: 200px;
  width: 200px;
  background: #131418;
  margin: 1em auto;
  display: inline-block
}

#navigation {
  position: fixed;
  top: 20px;
  left: 25%;
  right:25%;
  z-index: 1;
  padding: 25px;
  border-top: 0.1px dotted;    
  border-bottom: 0.1px dotted;
  background: white url(http://svgur.com/i/42T.svg) top left/cover no-repeat fixed;
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
  background: white url(http://svgur.com/i/42T.svg) top left/cover no-repeat fixed;
}
<div id="main">

  <div id="navigation">
    <button id="btn1">Button</button>
    <button id="btn2">Button</button>
    <button id="btn3">Button</button>
    <button id="btn4">Button</button>
  </div>

  <div id="card-wrapper">
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
  </div>

</div>

Ответ 6

Если вы не против иметь фиксированное значение для кнопок height, то ваша задача может быть решена с помощью стиля background-clip. В приведенном ниже примере я также добавил обработчики кликов для карточек и кнопок, чтобы продемонстрировать, что карты по-прежнему доступны для просмотра.

$('.card').on('click',function(){
  $(this).addClass('clicked');
})
$('button').on('click',function(){
  $('.card').removeClass('clicked');
})
#card-wrapper {
  width: 250px;
  margin: 100px auto;
}

.card {
  height: 200px;
  width: 200px;
  background: #131418;
  margin: 1em auto;
  display: inline-block
}

#navigation {
  background-image: url(http://svgur.com/i/42T.svg);
  background-attachment: fixed;
  background-size: cover;
  background-clip: content-box;
  border: 0 none;
  padding: 0;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  position: fixed;
  z-index: 1;
  box-sizing: border-box;
/**
calc() calculation values:
 25px - .buttons-list padding  
 20px - top offset of #navigation (it is also padding-top value)
 30px - button height;
*/
  padding: 20px 0 calc(100vh - 25px * 2 - 20px - 30px);
  pointer-events: none;
}

button {
  height: 30px
}

#main {
  text-align: center;
}

body {
  margin: 0 auto;
  background: url(http://svgur.com/i/42T.svg);
  background-attachment:fixed;
  background-size:cover;
}

.buttons-list {
  padding: 25px;
  pointer-events: initial;
}

/* Just for click events demonstration */
.card.clicked{
  background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">

  <div id="navigation">
    <div class="buttons-list">
      <button id="btn1">Button</button>
      <button id="btn2">Button</button>
      <button id="btn3">Button</button>
      <button id="btn4">Button</button>
    </div>
  </div>

  <div id="card-wrapper">
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
    <div class="card"></div>
  </div>

</div>