Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS3 Transition from fixed to absolute

Fixed on scroll

I created a logo element which is absolutely positioned in the document and, when I scroll over it stick on the top of the window with a fixed position (an example here : https://jsfiddle.net/swzbe9cv/2)

JavaScript

  window.addEventListener('scroll', fixLogo);
  function fixLogo(){
    if(window.scrollY >= trigger){
      if(!logo.classList.contains('fixed')){
        logo.classList.add('fixed');
      }
    } else{
      if(logo.classList.contains('fixed') && !nav.classList.contains('show')){
        logo.classList.remove('fixed');
      }
    }
  }

CSS

.logo {
  position: absolute;
  top: calc(100% + 15px);
  height: 40px;
  width: 100px;
}

.fixed {
  position: fixed;
  top: 15px;
}

With a menu appearing

I then decided to add a menu on the left which is showed/hided by a click on the logo element. This menu got a fixed position and the logo as to be on top of it when it is showed. (example here: https://jsfiddle.net/6cskthuz/2/) JavaScript

  logo.addEventListener('click',showMenu);
  function showMenu(){
    if(nav.classList.contains('show')){
      if(window.scrollY < pageheight && logo.classList.contains('fixed')){
        logo.classList.remove('fixed');
      }
      nav.classList.remove('show');
    } else {
      if(!logo.classList.contains('fixed')){
        logo.classList.add('fixed');
      }
      nav.classList.add('show');
    }
  }

CSS

nav {
  z-index:1;
  position: fixed;
  top: 0px;
  left: -8vw;
  width: 8vw;
  height: 100%;
  background-color: rgba(0,0,0,0.7);
  transition: 1s;
  padding-top: 8vw;
  text-align: center;
  font-size: 2rem;
}
.show {
  left: 0px;
}

How could I make a smooth translation of the logo element on top of menu when the menu appear and the logo is in absolute position?

I would like to do it CSS only at best, without jQuery at least.

PS: I found two related questions: 1. this one about relative to fixed/absolute positioning 2. And this one which appears to be unresolved but similar

like image 555
PaulCo Avatar asked Jan 07 '16 18:01

PaulCo


People also ask

How do you move an element with an absolute position?

Absolute Positioning You can use two values top and left along with the position property to move an HTML element anywhere in the HTML document. Move Left - Use a negative value for left. Move Right - Use a positive value for left. Move Up - Use a negative value for top.

How do you use position absolute and fixed?

Absolutely positioned elements are positioned with respect to a containing block, which is the nearest postioned ancestor. If there is no positioned ancestor, the viewport will be the containing block. Elements with fixed positioning are fixed with respect to the viewport—the viewport is always their containing block.

What can I use instead of absolute position?

We can use CSS absolute positioning to overlap elements, but there's some advantages to using CSS grid instead.

What is the difference between position absolute and fixed in CSS?

An element with position: absolute; is positioned relative to the nearest positioned ancestor (instead of positioned relative to the viewport, like fixed). However; if an absolute positioned element has no positioned ancestors, it uses the document body, and moves along with page scrolling.


1 Answers

The transition property in CSS works in a step-by-step process; the start value and end value have to be the same format. Unfortunately, position: fixed; and position: absolute; are two totally different values, even though they're both property values.

The behavior you're looking for does exist in CSS, and is called sticky positioning (which has issues in tables in Chromium browsers). Here's a working demo of that (make sure you use a supported browser):

html, body {
    margin: 0;
}

body * {
    margin: 20px;
    padding: 20px;
}

.header {
    margin: 0;
    padding: 20px;
    background: #000;
}

.header span {
    display: block;
    color: #fff;
    margin: 0 auto;
    text-align: center;
    padding: 0;
}

.placeholder {
    border: 1px solid black;
    margin: 0 auto;
    text-align: center;
    height: 300px;
}

.slider {
    background: #006264;
    color: white;
    font-weight: bold;
    margin: 0 auto;
    position: sticky;
    -webkit-position: sticky;
    top: 0px;
}
<div class="header"><span>This is a header</span></div>
<div class="placeholder">This div holds place</div>
<div class="slider">This should slide up and then stick.</div>
<div class="placeholder">This div holds place</div>
<div class="placeholder">This div holds place</div>
<div class="placeholder">This div holds place</div>
<div class="placeholder">This div holds place</div>

So you'll need to use JavaScript if you want broad support for the behavior, and you'll need to use JavaScript to add a smooth "transition" animation, too.

like image 117
TylerH Avatar answered Oct 01 '22 15:10

TylerH