2

I'm creating a website on my own using html+css and jquery. Recently started using SASS that comes with Autoprefixe just so I can get some formatting done more easily and be able to use sass libraries down the line.

I'm trying to apply a gradient alpha mask to some menu items that I've gotten to loop in a "marquee style".

I started by creating the image for the mask in a background-image tag. The idea is that there are two boxes above and under the menu, because of how alpha fade works, black part will be clearest when the mask is applied and the transparent part of the boxes will be where the text disappears. After some tweaking I got it looking like this:

enter image description here

.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%);
  }

But when I switch the background-image property to mask-image, it doesn't really mask the marquee-content(menu items). In fact it seems like the black boxes just disappear, with no masking happening whatsoever.

enter image description here

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

At this point I'm not exactly sure what's going wrong, the same happens on firefox, even though I use autoprefixer, which means that I'm not doing something right on the logic side. From what I read alpha masks should apply to children of elements as well, so my masks should be masking out marquee-content.

Here's my HTML structure for reference

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

So yeah, I've been banging my head on the wall for this, Any help or suggestions are very much welcome! Is there another way to achieve this effect? A better one? Am I just bad?

*I also did the masks with rgb and rgba intentionally to see if it was an issue. It wasn't. :<

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Paris Laras
  • 31
  • 1
  • 1
  • 7

1 Answers1

4

Here is a CSS only version

Sadly SO does not support SCSS (AFIK) – why I made a commented version here:

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>
Jakob E
  • 4,476
  • 1
  • 18
  • 21
  • This is a great deal of work, thanks! Gonna try it out and return with feedback. I'm learning a lot over here, and that aria-hidden is a very good tool, I haven't been doing accessibility enough on this project to be honest. Despite your answer though, I'm still not sure what was going wrong with my mask? I will A-B your code with mine tonight. Is it because of the background the pseudo-elements inherit? – Paris Laras Jun 28 '20 at 15:58