Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS change color on scroll / cut text - overflow z-index

I want to change the color of a position:fixed menu when scrolling.

enter image description here

My first intention was to use two fixed menus and overflow:hidden but it doesn't work on fixed elements. My second try was using z-index. But it seems impossible.

Maybe someone has an idea?

like image 717
bench-o Avatar asked Dec 15 '14 13:12

bench-o


3 Answers

What you are looking for is clipping. This allows you to specify a rectangular region where an element is visible.

You can use:

clip: rect(auto, auto, auto, auto);

on the container to emulate overflow: hidden for the position: fixed menu, so you can crop the text as you scroll.

Note that while clip is deprecated, the new clip-path does not work with position: fixed elements, so you are stuck with clip for now.

clip requires absolute or fixed positioning, but you can easily work around that problem by placing a position: absolute element inside a position: relative container, like so:

<div style="position: relative;">
    <div style="position: absolute; clip: rect(auto, auto, auto, auto);">
        <!-- My awesome menu here -->
    </div>
</div>

Here is the demo:

html,
body {
  height: 100%;
  margin: 0;
  padding: 10% 5% 80% 5%;
  background-color: #eee;
  font-family: sans-serif;
}
.container {
  display: table;
  width: 100%;
  height: 100%;
  background-color: #fff;
}
.row {
  display: table-row;
}
.cell {
  display: table-cell;
  position: relative;
}
.cell.small {
  height: 25%;
}
.header,
.content,
.footer {
  position: absolute;
  width: 100%;
  height: 100%;
  padding: 4%;
  box-sizing: border-box;
  clip: rect(auto, auto, auto, auto);
}
.header,
.footer {
  background-color: #F97D9F;
}
.menu {
  position: fixed;
  font-size: 2em;
  top: 10%;
  right: 20%;
}
.white {
  color: #fff;
}
.black {}
<div class="container">
  <div class="row">
    <div class="cell small">
      <div class="header">
        content
        <div class="menu white">MENU</div>
      </div>
    </div>
  </div>
  <div class="row">
    <div class="cell">
      <div class="content">
        content
        <div class="menu black">MENU</div>
      </div>
    </div>
  </div>
  <div class="row">
    <div class="cell small">
      <div class="footer">
        content
        <div class="menu white">MENU</div>
      </div>
    </div>
  </div>
</div>
like image 124
Antony Avatar answered Nov 17 '22 18:11

Antony


The behaviour you are looking for is the same as background-attachement:fixed;.

Although this solution is pretty simple and doesn't rely on JS, from a sematic point of view it shouldn't be recommended.

The point is to use 2 background images with background-attachement: fixed; and to position the link over them for interaction. It will give you the desired behaviour with a smooth color change according to the background color :

DEMO

header, article,footer,body{
    background:#fff url('http://i.imgur.com/oHIZBHL.png') no-repeat;
    background-attachment: fixed;
    background-position:right 160px top 10px;
}
body{
    padding:0 150px 1000px;
    background-color:lightgrey;
}
header,footer{
    background-image:url('http://i.imgur.com/79IWeQK.png');
    background-color:#F97D9F;
    height:125px;
}
article{
    height:500px;
}
nav a{
    position:fixed;
    top:10px; right:160px;
    width:150px; height:50px;
}
<nav><a href="#" title="menu"></a></nav>
<header></header>
<article></article>
<footer></footer>
like image 9
web-tiki Avatar answered Nov 17 '22 18:11

web-tiki


If you don't want to have to manage duplicate elements to pull off this effect with CSS clip as per Antony's solution, then you can use a couple jQuery plugins:

  • jq-clipthru - This is a superflexible plugin that can probably do everything you want (and a lot more), but it also requires the jQuery UI library. [Demo]

  • Unobscure Text - This is my very lightweight plugin that has a very specific use case, but it's not compatible with jQuery 3. [Demo]

If you require jQuery 3 support and don't care for IE 11 and below, then you can use a solution based on SVG clip-path, like this.

like image 2
thdoan Avatar answered Nov 17 '22 20:11

thdoan