CSS Div 淡入淡出滚动样式

问题描述 投票:0回答:1

我似乎不知道如何设计如下图所示的可滚动 div 的样式。我发现的教程和示例都将 div 淡出为背景颜色,但我找不到这样的,有人有解决方案吗?不需要有下面的内部div和标题,只需要保持白框不褪色,谢谢!

html css scroll styling
1个回答
14
投票

您可以使用 CSS

mask-image
对于支持它的浏览器(这现在很常见)。根据您的需求,可能需要 JS(例如,如果您想根据用户是否滚动到元素的最顶部/底部来有条件地切换淡入淡出)。

要创建“底部淡出”效果,您可以使用以下 CSS 规则:

mask-image: linear-gradient(to bottom, black calc(100% - 48px), transparent 100%);

它基本上是说:

  • 创建从顶部到底部的线性渐变
  • 当我们距离底部48px时,开始将颜色从黑色(遮罩时看穿)更改为透明(遮罩时不透明)

但是,这只会创建底部渐变。要遮盖顶部和底部,您需要将两个渐变合并为一个:

mask-image: linear-gradient(to bottom, transparent 0%, black 48px, black calc(100% - 48px), transparent 100%);

现在你问:我们如何隐藏面具?简单:如果色标间隔 0 像素,则遮罩将整个为黑色,这将使其完全透明。

JS 部分只是使用类切换这些颜色停止点。我们使用 CSS 自定义属性,可以通过添加/删除类来覆盖这些属性。 JS 用于嗅探滚动位置并切换这些类。请参阅下面的概念验证:

function setClasses(el) {
  const isScrollable = el.scrollHeight > el.clientHeight;
  
  // GUARD: If element is not scrollable, remove all classes
  if (!isScrollable) {
    el.classList.remove('is-bottom-overflowing', 'is-top-overflowing');
    return;
  }
  
  // Otherwise, the element is overflowing!
  // Now we just need to find out which direction it is overflowing to (can be both).
  // One pixel is added to the height to account for non-integer heights.
  const isScrolledToBottom = el.scrollHeight < el.clientHeight + el.scrollTop + 1;
  const isScrolledToTop = isScrolledToBottom ? false : el.scrollTop === 0;
  el.classList.toggle('is-bottom-overflowing', !isScrolledToBottom);
  el.classList.toggle('is-top-overflowing', !isScrolledToTop);
}

document.querySelector('#content').addEventListener('scroll', (e) => {
  const el = e.currentTarget;
  setClasses(el);
});

setClasses(document.querySelector('#content'));
* {
  box-sizing: border-box;
}

body {
  padding: 0;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background-color: #2a9d8f;
  font-family: Arial, sans-serif;
}

.box {
  width: 50vw;
  height: 90vh;
  background-color: #fff;
  border-radius: 16px;
  padding: 32px;
  display: flex;
  flex-direction: column;
}

.box h1 {
  margin: 0;
}

#content {
  overflow-y: auto;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, black var(--top-mask-size, 0), black calc(100% - var(--bottom-mask-size, 0)), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, black var(--top-mask-size, 0), black calc(100% - var(--bottom-mask-size, 0)), transparent 100%);
  --top-mask-size: 0px;
  --bottom-mask-size: 0px;
}

#content.is-top-overflowing {
  --top-mask-size: 48px !important;
}

#content.is-bottom-overflowing {
  --bottom-mask-size: 48px !important;
}
<article class="box">
  <h1>Lorem ipsum</h1>
  <section id="content">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque vel metus at tellus consectetur rhoncus. Aenean euismod eget mauris cursus tincidunt. Cras lectus dolor, suscipit nec porttitor a, tincidunt vel arcu. Etiam facilisis faucibus lectus
      vitae pharetra. Fusce euismod lacus sit amet consequat mattis. Aliquam suscipit metus a nulla suscipit varius. In tempor suscipit pretium.</p>
    <p>Vivamus aliquam eros eu orci finibus, id efficitur lorem placerat. Sed congue ipsum quis accumsan feugiat. Nunc imperdiet faucibus tellus, nec tincidunt ipsum dictum non. Quisque dui lacus, bibendum vitae lectus vel, vulputate tempus quam. Praesent
      ullamcorper ultricies felis, at fermentum massa gravida quis. Pellentesque mollis, urna sed vehicula elementum, dolor lorem congue ipsum, eget ullamcorper ex arcu nec mi. Suspendisse potenti. Morbi pharetra eu nisi quis laoreet. Donec ut quam id
      justo pulvinar volutpat eget ut magna.</p>
    <p>Etiam aliquam eleifend dignissim. Donec sagittis tincidunt quam, eget venenatis mi sollicitudin et. Vestibulum id lectus mi. Aenean enim sem, viverra at velit ut, posuere dapibus tellus. Ut accumsan mi eu lectus sollicitudin ornare. Morbi eu semper
      lacus lacus. Aenean id erat at nulla ornare consequat a at leo. In risus risus, blandit sit amet tortor sed, accumsan porttitor velit. Quisque interdum id ipsum quis convallis. Suspendisse vel pretium augue. Sed tincidunt, felis ut porta consectetur,
      mauris urna hendrerit diam, nec aliquet augue ante quis metus.</p>
  </section>
</article>

© www.soinside.com 2019 - 2024. All rights reserved.