【问题标题】:How do I apply a proper gradient alpha mask with CSS (over text)?如何使用 CSS(在文本上)应用适当的渐变 alpha 蒙版?
【发布时间】:2020-06-27 19:43:15
【问题描述】:

我正在使用 html+css 和 jquery 自己创建一个网站。 最近开始使用带有 Autoprefixe 的 SASS,这样我就可以更轻松地完成一些格式化并能够使用 sass 库。

我正在尝试将渐变 alpha 蒙版应用于某些菜单项 我已经进入了“选框风格”的循环。

我首先在 background-image 标记中为蒙版创建图像。 这个想法是菜单上方和下方有两个框,因为 alpha 淡入淡出的工作原理,当应用蒙版时黑色部分将最清晰,而框的透明部分将是文本消失的地方。经过一些调整后,我得到了它的样子:

.marquee:before {
    transform: translateX(-50%);
    top: 0;
    background-image: linear-gradient(to top,rgb(0, 0, 0) 0%, transparent 100%);
  }
  .marquee:after {
    bottom:0;
    background-image: linear-gradient(to bottom,rgba(0, 0, 0, 100) 0%, rgba(0, 0, 0, 0) 100%);
    transform: translateX(-50%);
  }

但是当我将 background-image 属性切换为 mask-image 时,它​​并没有真正掩盖 marquee-content(菜单项)。事实上,黑匣子似乎只是消失了,没有发生任何掩蔽。

.marquee {
    width: var(--marquee-width);
    height: 30vh;
    overflow: hidden;
    position: relative;
  }

  .marquee:before, .marquee:after {
    position: absolute;
    width: var(--marquee-width);
    height: 1.5rem;
    content: "";
    z-index: 1;
  }
  .marquee:before {
    transform: translateX(-50%);
    top: 0;
    mask-image: linear-gradient(to top,rgb(0, 0, 0) 0%, transparent 100%);
  }
  .marquee:after {
    bottom:0;
    mask-image: linear-gradient(to bottom,rgba(0, 0, 0, 100) 0%, rgba(0, 0, 0, 0) 100%);
    transform: translateX(-50%);
  }
  .marquee-content {
    margin-bottom:-1vh;
    list-style: none;
    height: 100%;
    display: inline-flexbox;
    animation: scrolling var(--marquee-animation-duration) linear infinite ;
    animation-delay: 4s;
  }

在这一点上,我不确定出了什么问题,即使我使用了 autoprefixer,在 Firefox 上也会发生同样的情况,这意味着我在逻辑方面没有做正确的事情。 从我读到的内容来看,alpha 蒙版也应该适用于元素的子元素,所以我的蒙版应该屏蔽掉选框内容。

这是我的 HTML 结构供参考

<!---Menu Container-->
<div class="menucontainer" id="fixedMenu">
    <nav class="nav">
        <li class=active></li>
        <li class="menutitle scrollTop" id="myTitle">CIVR1</a></li>
        <ul class="marquee">
            <ul class="marquee-content">
                <li><a class="menuitems nav-section1" href="#TheInitiator">the initiator</a></li>
                <li><a class="menuitems nav-section2" id="m2" href="#TheJourney">the journey</a></li>
                <li><a class="menuitems nav-section3" id="m3" href="#PatronOfTheSea">patron of the sea</a></li>
                <li><a class="menuitems nav-section4" id="m4" href="#ExtremeBodies">extreme bodies</a></li>
                <li><a class="menuitems nav-section5" id="m5" href="#DownloadVR">download vr</a></li>
                <li><a class="menuitems nav-section6" id="m6" href="#PerformanceLibrary">performance library</a></li>
                <li><a class="menuitems nav-section7" id="m7" href="#Partners">partners</a></li>
                <li><a class="menuitems nav-section8" id="m8" href="#Contact">contact</a></li>
            </ul>
        </ul>
    </nav>
</div>

所以,是的,我一直为此苦苦挣扎, 非常欢迎任何帮助或建议! 有没有其他方法可以达到这种效果?一个更好的? 我只是坏了吗?

*我还特意用 rgb 和 rgba 制作了蒙版,看看是否有问题。不是。 :

【问题讨论】:

标签: html css css-animations css-mask


【解决方案1】:

这是一个纯 CSS 版本

遗憾的是,SO 不支持 SCSS (AFIK)——为什么我在这里制作了一个注释版本:

CSS Only Navigation Marquee

/* –––––––––––––––––––––––
    fonts + reset
   ––––––––––––––––––––––– */
@import url('https://fonts.googleapis.com/css?family=Montserrat:400,400i,700,700i');
*,
*::before,
*::after {
    box-sizing: border-box;
}

body {
    margin: 0;
    background: #525659;
}


/* –––––––––––––––––––––––
    pseudo element masks
   ––––––––––––––––––––––– */
header {
    /* layout */
    position: relative;
    display: -webkit-box;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    flex-direction: column;
    -webkit-box-pack: center;
    justify-content: center;
    padding: 20px;

    /* background image */
    background-image: url(//unsplash.it/800/400/?image=172);
    background-size: cover;
    background-position: bottom left;

    /* typography */
    font-family: 'Montserrat';
    font-weight: 700;
    font-style: italic;
    text-align: center;
    color: lightblue;
}

/* –––––––––––––––––––––––
    pseudo element masks
   ––––––––––––––––––––––– */
header::before,
header::after {
    /*  cover entire header element */
    position: absolute;
    content: '';
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;

    /* inherit the header background properties 
       (makes it easier to mauntain) */
    background: inherit;

    /* disable pointer events to allow 
       links to be clickable */
    pointer-events: none;
    z-index: 1;
}

header::before {
    /* 80px  is the distance from nav top to marquee top 
       fades out distance 40px (80px + 40px = 120px) */
    -webkit-mask-image: linear-gradient(to bottom, black 80px, transparent 120px);
    mask-image: linear-gradient(to bottom, black 80px, transparent 120px);
}
header::after {
    /* 20px is the distance from nav bottom to marquee bottom       
       fades out distance 40px (20px + 40px = 60px) */
    -webkit-mask-image: linear-gradient(to top, black 20px, transparent 60px);
    mask-image: linear-gradient(to top, black 20px, transparent 60px);
}



/* –––––––––––––––––––––––
    h1 heading
   ––––––––––––––––––––––– */
header h1 {
    /*  place header above masks */
    z-index: 2;
    font-size: 1.4rem;
    text-shadow: 1px 1px rgba(0, 0, 0, 0.5);
}



/* –––––––––––––––––––––––
    nav/marquee
   ––––––––––––––––––––––– */
header nav {
    /* reset list style */
    list-style: none;
    overflow: hidden;
    margin: 0;
    padding: 0;

    /* set the height based on 8 items times 20px */
    height: 160px;
}



/* –––––––––––––––––––––––
    links 
   ––––––––––––––––––––––– */
header nav a {
    /*  block/inline-block allows transforms */
    display: block;
    height: 20px;

    color: inherit;
    text-transform: uppercase;
    text-decoration: none;
    text-shadow: 1px 1px rgba(0, 0, 0, 0.5);

    /* animation - see below */
    -webkit-animation: anim 4000ms linear infinite;
    animation: anim 4000ms linear infinite;
}


header nav a:hover {
    color: dodgerblue;
}


/* –––––––––––––––––––––––
    animation

    translate links up by the height of the marquee
    this way you see the repeated items before 
    the animation returns to its initial state 
   ––––––––––––––––––––––– */
@-webkit-keyframes anim {
    to {
        -webkit-transform: translateY(-160px);
        transform: translateY(-160px);
    }
}
@keyframes anim {
    to {
        -webkit-transform: translateY(-160px);
        transform: translateY(-160px);
    }
}



/* pause the animation on hover */
header nav:hover a {
    -webkit-animation-play-state: paused;
    animation-play-state: paused;
}
<header>
  <h1>CIVR1</h1>

  <nav>
    <a href="#TheInitiator">the initiator</a>
    <a href="#TheJourney">the journey</a>
    <a href="#PatronOfTheSea">patron of the sea</a>
    <a href="#ExtremeBodies">extreme bodies</a>
    <a href="#DownloadVR">download vr</a>
    <a href="#PerformanceLibrary">performance library</a>
    <a href="#Partners">partners</a>
    <a href="#Contact">contact</a>

    <!-- 
      repeat items to allow endless loop
      (hide from screen readers)
    -->
    <a aria-hidden="true" href="#TheInitiator">the initiator</a>
    <a aria-hidden="true" href="#TheJourney">the journey</a>
    <a aria-hidden="true" href="#PatronOfTheSea">patron of the sea</a>
    <a aria-hidden="true" href="#ExtremeBodies">extreme bodies</a>
    <a aria-hidden="true" href="#DownloadVR">download vr</a>
    <a aria-hidden="true" href="#PerformanceLibrary">performance library</a>
    <a aria-hidden="true" href="#Partners">partners</a>
    <a aria-hidden="true" href="#Contact">contact</a>
  </nav>
</header>

【讨论】:

  • 这项工作量很大,谢谢!会尝试一下并返回反馈。我在这里学到了很多东西,而且 aria-hidden 是一个非常好的工具,老实说,我在这个项目上的可访问性还不够。尽管您回答了,但我仍然不确定我的面具出了什么问题?今晚我将用我的代码来 A-B。是不是因为伪元素继承的背景?
猜你喜欢
  • 1970-01-01
  • 2011-11-11
  • 1970-01-01
  • 2012-03-20
  • 2016-07-06
  • 2021-11-21
  • 1970-01-01
  • 2011-11-27
相关资源
最近更新 更多