[css] CSS: fixed position on x-axis but not y?

Is there a way to fix a position on the x-axis only? So when a user scrolls up, the div tag will scroll up with it, but not side to side?

This question is related to css

The answer is


Yes, You actually can do that only by using CSS...

body { width:100%; margin-right: 0; margin-left:0; padding-right:0; padding-left:0; }

Tell me if it works


If your block is originally positioned as static, you may want to try this

_x000D_
_x000D_
$(window).on('scroll', function () {_x000D_
_x000D_
  var $w = $(window);_x000D_
  $('.position-fixed-x').css('left', $w.scrollLeft());_x000D_
  $('.position-fixed-y').css('top', $w.scrollTop());_x000D_
_x000D_
});
_x000D_
.container {_x000D_
  width: 1000px;_x000D_
}_x000D_
_x000D_
.position-fixed-x {_x000D_
  position: relative; _x000D_
}_x000D_
_x000D_
.position-fixed-y {_x000D_
  position: relative;_x000D_
}_x000D_
_x000D_
.blue-box {_x000D_
  background:blue;_x000D_
  width: 50px;_x000D_
  height: 50px;_x000D_
}_x000D_
_x000D_
.red-box {_x000D_
  background: red;_x000D_
  width: 50px;_x000D_
  height: 50px;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<div class="container">_x000D_
_x000D_
<div class="position-fixed-y red-box">_x000D_
  _x000D_
</div>_x000D_
_x000D_
The pattern of base pairs in the DNA double helix encodes the instructions for building the proteins necessary to construct an entire organism. DNA, or deoxyribonucleic acid, is found within most cells of an organism, and most organisms have their own unique DNA code. One exception to this is cloned organisms, which have the same exact DNA code as their parents do._x000D_
_x000D_
<div class="position-fixed-x blue-box">_x000D_
  _x000D_
</div>_x000D_
_x000D_
DNA strands are composed of millions of sub-units, called nucleotides. Each nucleotide contains a 5-carbon sugar, a phosphate group and a nitrogen base. There are four different variations of the nitrogen base group, responsible for all of the variation between two different DNA strands. The four different variations are called adenine, guanine, cytosine and thymine, but they are typically abbreviated and only referred to by their first letter. The sequence of these different nitrogen bases makes up the code of the DNA._x000D_
_x000D_
The DNA strand splits in two, and forms two different DNA strands during cell replication. However, sometimes this process is not perfect, and mistakes occur. These mistakes may change the way an organism is constructed or functions. When this happens, it is called a mutation. These mutations can be helpful or harmful, and they are usually passed on to the organism’s offspring._x000D_
  _x000D_
 The traits of a living thing depend on the complex mixture of interacting components inside it. Proteins do much of the chemical work inside cells, so they largely determine what those traits are. But those proteins owe their existence to the DNA (deoxyribonucleic acid), so that is where we must look for the answer._x000D_
The easiest way to understand how DNA is organized is to start with its basic building blocks. DNA consists of four different sugars that interact with each other in specific ways. These four sugars are called nucleotide bases and have the names adenine (A), thymine (T), cytosine (C) and guanine (G). Think of these four bases as letters in an alphabet, the alphabet of life!_x000D_
If we hook up these nucleotides into a sequence--for example, GATCATCCG--we now have a little piece of DNA, or a very short word. A much longer piece of DNA can therefore be the equivalent of different words connected to make a sentence, or gene, that describes how to build a protein. And a still longer piece of DNA could contain information about when that protein should be made. All the DNA in a cell gives us enough words and sentences to serve as a master description or blueprint for a human (or an animal, a plant, or a microorganism)._x000D_
Of course, the details are a little more complicated than that! In practice, active stretches of DNA must be copied as a similar message molecule called RNA. The words in the RNA then need to be "read" to produce the proteins, which are themselves stretches of words made up of a different alphabet, the amino acid alphabet. Nobel laureates Linus Pauling, who discerned the structure of proteins, and James Watson and Francis Crick, who later deciphered the helical structure of DNA, helped us to understand this "Central Dogma" of heredity--that the DNA code turns into an RNA message that has the ability to organize 20 amino acids into a complex protein: DNA -> RNA -> Protein._x000D_
To understand how this all comes together, consider the trait for blue eyes. DNA for a blue-eyes gene is copied as a blue-eyes RNA message. That message is then translated into the blue protein pigments found in the cells of the eye. For every trait we have--eye color, skin color and so on--there is a gene or group of genes that controls the trait by producing first the message and then the protein. Sperm cells and eggs cells are specialized to carry DNA in such a way that, at fertilization, a new individual with traits from both its mother and father is created._x000D_
</div>
_x000D_
_x000D_
_x000D_


$(window).scroll(function(){
    $('#header').css({
        'left': $(this).scrollLeft() + 15 
         //Why this 15, because in the CSS, we have set left 15, so as we scroll, we would want this to remain at 15px left
    });
});

Thanks


Sounds like you need to use position:fixed and then set the the top position to a percentage and the and either the left or the right position to a fixed unit.


Starx's solution was extremely helpful to me. But I had some problems when I tried to implement a vertical scrolling sidebar with it. Here was my initial code, based on what Starx wrote:

function fix_vertical_scroll(id) {
    $(window).scroll(function(){
        $(id).css({
            'top': $(this).scrollTop() //Use it later
        });
    });
}

It's slightly different from Starx's solution, because I think his code is designed to allow a menu to float horizontally instead of vertically. But that's just an aside. The problem I had with the above code is that in a lot of browsers, or depending on the resource load of the computer, the menu movements would be choppy, whereas the initial css solution was nice and smooth. I attribute this to browsers being slower at firing javascript events than at implementing css.

My alternate solution to this choppiness problem is set the frame to fixed instead of absolute, then cancel out the horizontal movements using starx's method.

function float_horizontal_scroll(id) {
    jQuery(window).scroll(function(){
        jQuery(id).css({
            'left': 0 - jQuery(this).scrollLeft()
        });
    });
}

#leftframe {
 position:fixed;
 width: 200;
}   

You might say all I'm doing is trading vertical scrolling choppiness for horizontal scrolling choppiness. But the thing is, 99% of scrolling is vertical, and it's much more annoying when that is choppy than when horizontal scrolling is.

Here's my related post on this matter, if I haven't already exhausted everyone's patience: Fixing a menu in one direction in jquery


No, it's not possible with pure CSS. That kind of positioning fixes the element in the viewport. I'd suggest simply fixing the element to one of the sides of the viewport (i.e. top, bottom, left or right) so that it doesn't interfere with other content.


If you want to fix it on the right, for example, use justify-content: flex-end.

More: http://www.w3schools.com/cssref/css3_pr_justify-content.asp


I realize this thread is mighty old but it helped me come up with a solution for my project.

In my case I had a header that I wanted to never be less than 1000px wide, header always on top, with content that could go unlimited right.

header{position:fixed; min-width:1024px;}
<header data-min-width="1024"></header>

    $(window).on('scroll resize', function () {
        var header = $('header');
        if ($(this).width() < header.data('min-width')) {
            header.css('left', -$(this).scrollLeft());
        } else {
            header.css('left', '');
        }
    });

This also should handle when your browser is less than your headers min-width


This is a very old thread, but I have found a pure CSS solution to this using some creative nesting. I wasn't a fan of the jQuery method at all...

Fiddle here: https://jsfiddle.net/4jeuv5jq/

<div id="wrapper">
    <div id="fixeditem">
        Haha, I am a header. Nah.. Nah na na na
    </div>
    <div id="contentwrapper">
        <div id="content">
            Lorem ipsum.....
        </div>
    </div>
</div>

#wrapper {
position: relative;
width: 100%;
overflow: scroll;
}

#fixeditem {
position: absolute;
}

#contentwrapper {
width: 100%;
overflow: scroll;
}

#content {
width: 1000px;
height: 2000px;
}

On parent div you can add

overflow-y: scroll; 
overflow-x: hidden;

Updated the script to check the start position:

function float_horizontal_scroll(id) {
var el = jQuery(id);
var isLeft = el.css('left') !== 'auto';
var start =((isLeft ? el.css('left') : el.css('right')).replace("px", ""));
jQuery(window).scroll(function () {
    var leftScroll = jQuery(this).scrollLeft();
    if (isLeft)
        el.css({ 'left': (start + leftScroll) + 'px' });
    else
        el.css({ 'right': (start - leftScroll) + 'px' });
});

}


Now that mobile is over 70% from the internet market you can create something smart and responsive to do that.

You can create this very easy with only css, use a overflow-x:scroll for a container and a overflow-y:scroll for another container. You can easily position the container elements with width:100vw and height:100vh.

Middle click on the example to test it. Works best on mobile because you dont see the scroll bars.

_x000D_
_x000D_
body{max-width:100%}_x000D_
*{box-sizing:border-box;}_x000D_
.container{background:#ddd;overflow-y:scroll;width:500px;max-height:100vh;}_x000D_
.header{background: pink;}_x000D_
.body{background: teal;padding:20px;min-width: 100%;overflow:scroll;overflow-y:hidden;min-height:300px;}_x000D_
.body >div{min-width:800px;}
_x000D_
<body>_x000D_
  <div class="container">_x000D_
    <div class="header">_x000D_
       Button 1 > Button 2 > Button 3_x000D_
    </div>_x000D_
    <div class="body">_x000D_
      <div>_x000D_
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum_x000D_
<br><br>_x000D_
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum_x000D_
<br><br>_x000D_
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum<br><br>_x000D_
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum<br><br>_x000D_
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum<br><br>_x000D_
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum<br><br>_x000D_
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum<br><br>_x000D_
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum_x000D_
     </div>_x000D_
    </div>_x000D_
  </div>_x000D_
</body>
_x000D_
_x000D_
_x000D_


Very easy solution is:

window.onscroll = function (){
  document.getElementById('header').style.left= 15 - (document.documentElement.scrollLeft + document.body.scrollLeft)+"px";
}

I stumbled on this post looking for a nice way to keep my header/navigation bar centered and responsive to size changes.

//CSS
.nav-container {
  height: 60px;  /*The static height*/
  width: 100%;  /*Makes it responsive to resizing the browser*/
  position: fixed;  /*So that it will always be in the center*/
}

//jQuery
$(window).scroll(() => {
  if ($(document).scrollTop() < 60) {
    $('.nav-container').css('top', $(document).scrollTop() * -1)
  }
})

As we scroll, the bar moves upwards off the screen. If you scroll left/right it will stay fixed.


Its a simple technique using the script also. You can check a demo here too.

JQuery

$(window).scroll(function(){
    $('#header').css({
        'left': $(this).scrollLeft() + 15 
         //Why this 15, because in the CSS, we have set left 15, so as we scroll, we would want this to remain at 15px left
    });
});

CSS

#header {
    top: 15px;
    left: 15px;
    position: absolute;
}

Update Credit: @PierredeLESPINAY

As commented, to make the script support the changes in the css without having to recode them in the script. You can use the following.

var leftOffset = parseInt($("#header").css('left')); //Grab the left position left first
$(window).scroll(function(){
    $('#header').css({
        'left': $(this).scrollLeft() + leftOffset //Use it later
    });
});

Demo :)


I just added position:absolute and that solved my problem.


This is an old thread but CSS3 has a solution.

position: sticky;

Have a look at this blog post.

Demonstration:

css position sticky animation

And this documentation.