修复了滚动Flex项目中的SVG位置

时间:2018-04-05 20:30:10

标签: css svg flexbox position css-position

我发现了一种将虚拟SVG阴影粘贴到滚动弹性项目底部的黑客方式。

有些尝试包括

  • position:absolute,但SVG最终位于flex容器的底部。
  • 一个Flex容器,其位置:相对于flex项目内部。在卷轴上,阴影最终漂浮在容器的中间。
  • position:sticky,直到你到达滚动的底部并且阴影向上移动~4px(这是translateY)。

在下面的代码中,我添加了第三个flex项目,并将SVG插入其中,然后移动顶部位置以模仿上面flex项目底部的阴影。

为什么不使用CSS阴影?这个特殊的阴影是我用CSS无法产生的内在阴影。也许你知道一种方式。

此解决方案的要求

  • 阴影必须保留在滚动容器的底部
  • 滚动容器具有动态高度

我欢迎提供更清洁解决方案的想法。

var box = document.querySelector(".box");
var flexItem = box.querySelector(".toggle--flex");
var flexButton = box.querySelector(".button__toggle--flex");

function toggleFlexDisplay() {
  if (flexItem.style.display === "none") {
    flexItem.style.display = "block";
  } else {
    flexItem.style.display = "none";
  }
}

flexButton.addEventListener("click", toggleFlexDisplay);
* { 
  font: 1em/1.3 Lato;
}
.box {
  background: #FCE65F;
  padding: 1em;
}
.flex {
  display: flex;
  height: 200px;
  flex-flow: column nowrap;
}
.flex__item {
  background: #F8CC37;
  margin: 0.5em 0;
  padding: 0.5em;
}
.flex__item--lighter {
  background: #EFEFEF;
  overflow-y: auto;
  flex: 1;
}
.flex__item--shadow {
  position: relative;
  padding: 0;
  margin: 0;
}
.spacer {
  height: 30px;
  background: #653533;
}
.shadow {
  position: absolute;
  top: -30px;
  left: 0;
  transform: translateY(4px);
}
button {
  border-radius: 4px;
  margin: 0.5em 0;
  padding: 0.5em 1em;
}
button:focus {
  outline: 0;
}
<div class="box">
      <div class="flex flex--column">
        <div class="flex__item flex__item--lighter">
          Duis gravida, elit iaculis varius pellentesque, eros dui luctus velit, a bibendum nulla nunc non magna. Cras laoreet, est at dignissim lacinia, mi justo blandit nulla, ut consequat lectus quam eu arcu. Aliquam non lectus sagittis, interdum augue sed,
          tempus elit. Cras ultricies volutpat justo, in porta ante laoreet vitae. Nunc vehicula feugiat rutrum. Nam et elit erat. Suspendisse risus mauris, ornare id posuere et, consectetur vel sem. Duis gravida, elit iaculis varius pellentesque, eros
          dui luctus velit, a bibendum nulla nunc non magna. Cras laoreet, est at dignissim lacinia, mi justo blandit nulla, ut consequat lectus quam eu arcu. Aliquam non lectus sagittis, interdum augue sed, tempus elit. Cras ultricies volutpat justo,
          in porta ante laoreet vitae. Nunc vehicula feugiat rutrum. Nam et elit erat. Suspendisse risus mauris, ornare id posuere et, consectetur vel sem.
        </div>
        <div class="flex__item flex__item--shadow">
          <svg class="shadow" height="18" width="100%">
            <defs>
              <filter id="gauss">
                <feGaussianBlur stdDeviation="4" />
              </filter>
            </defs>
            <line x1="0" x2="100%" y1="18" y2="18" stroke="red" stroke-width="2" />
            <rect x="2%" y="7" rx="10" ry="5" width="96%" height="40" fill="red" fill-opacity="0.5" filter="url(#gauss)" /> Sorry, your browser does not support inline SVG.
          </svg>
        </div>
        <div class="flex__item toggle--flex" style="display:block; position:relative;">
          <div class="spacer"></div>
        </div>
      </div>
      <button class="button__toggle--flex">Toggle Flex Item </button>
    </div>

1 个答案:

答案 0 :(得分:1)

您可以使用多个CSS插入框阴影来实现此目的。他们会叠加在一起。红色的一个将沿着底部一直向前移动,你可以使用白色的边缘重叠边缘,给人一种幻觉,即红色的阴影不会从头到尾一路走来。

box-shadow: 
    inset -25px 8px 8px 1px #EFEFEF, //this stacks on top of the red one
    inset 25px 8px 8px 1px #EFEFEF, //this stacks on top of the red one
    inset 0 -13px 10px 0 rgba(255,0,0,0.5); //bottom shadow

这里它们适用于原始代码段上的.flex__item - 更轻:

var box = document.querySelector(".box");
var flexItem = box.querySelector(".toggle--flex");
var flexButton = box.querySelector(".button__toggle--flex");

function toggleFlexDisplay() {
  if (flexItem.style.display === "none") {
    flexItem.style.display = "block";
  } else {
    flexItem.style.display = "none";
  }
}

flexButton.addEventListener("click", toggleFlexDisplay);
* {
  font: 1em/1.3 Lato;
}

.box {
  background: #FCE65F;
  padding: 1em;
}

.flex {
  display: flex;
  height: 300px;
  flex-flow: column nowrap;
}

.flex__item {
  background: #F8CC37;
  margin: 0.5em 0;
  padding: 0.5em;
}

.flex__item--lighter {
  background: #EFEFEF;
  overflow-y: auto;
  flex: 1;
  position: relative;
  border-bottom: 1px solid red;
  box-shadow: inset 10px 20px 30px 5px #fff,
              inset -10px 20px 30px 5px #fff,
              inset 0px -5px 20px 0px rgba(255, 0, 0, 0.7);
}

.flex__item--shadow {
  position: relative;
  padding: 0;
  margin: 0;
}

.spacer {
  height: 30px;
  background: #653533;
}

.shadow {
  position: absolute;
  top: -30px;
  left: 0;
  transform: translateY(4px);
}

button {
  border-radius: 4px;
  margin: 0.5em 0;
  padding: 0.5em 1em;
}

button:focus {
  outline: 0;
}
<div class="box">
  <div class="flex flex--column">
    <div class="flex__item flex__item--lighter">
      Duis gravida, elit iaculis varius pellentesque, eros dui luctus velit, a bibendum nulla nunc non magna. Cras laoreet, est at dignissim lacinia, mi justo blandit nulla, ut consequat lectus quam eu arcu. Aliquam non lectus sagittis, interdum augue sed,
      tempus elit. Cras ultricies volutpat justo, in porta ante laoreet vitae. Nunc vehicula feugiat rutrum. Nam et elit erat. Suspendisse risus mauris, ornare id posuere et, consectetur vel sem. Duis gravida, elit iaculis varius pellentesque, eros dui
      luctus velit, a bibendum nulla nunc non magna. Cras laoreet, est at dignissim lacinia, mi justo blandit nulla, ut consequat lectus quam eu arcu. Aliquam non lectus sagittis, interdum augue sed, tempus elit. Cras ultricies volutpat justo, in porta
      ante laoreet vitae. Nunc vehicula feugiat rutrum. Nam et elit erat. Suspendisse risus mauris, ornare id posuere et, consectetur vel sem.


    </div>

    <div class="flex__item toggle--flex" style="display:block; position:relative;">
      <div class="spacer"></div>
    </div>
  </div>
  <button class="button__toggle--flex">Toggle Flex Item </button>
</div>