Sticky header CSS when header is unknown height - css

I can see quite a lot of articles online about how to create sticky headers (ie. when the user scrolls the page, the header stays in place at the top of the window). However they all seem to imply that the header should be of a fixed height?
This is unacceptable for me. For a very simple example, on certain dates like July 4 I might want to put a USA flag in the header - which will slightly increase the height.
So how can I make a header, say all contained within a <div class="header"> ... </div> area, sticky - regardless of the height of the div?

Sorry to be late to the party, but this can be done without any Javascript at all. This may be aesthetically unpleasing, an offense against god and man, but it does work! The trick is to put precisely the same content in two div's:
<div id="fbanner">Here's your banner content</div>
<div id="banner">Here's your banner content</div>
<div id="restofpage">Here's the stuff on the rest of your page</div>
Then provide some CSS:
#fbanner {
position: fixed;
width: 100%;
}
#banner {
visibility: hidden;
}
So, no matter what the content is, even if it's text that line-wraps in a narrow viewport, both div's will be the same height, and the hidden one will take up the space needed to keep the rest of the page content from disappearing under the banner until you scroll.
You might find that you have to do some tinkering with margins, but that's a small price to pay if you want to avoid yet another jQuery "solution."

You have to use jquery for this. jquery get the height of the header dynamically and put the padding top on bellow the heard div.
For example
HTML
<html>
<head>test</head>
<body>
<header>
<div class="example"> Test</div>
</header>
<div class="sample-content">
Test Content Test Content Test Content Test Content Test Content
</div>
CSS
header{width:100%; position:fixed;}
JQUERY
<script>
$(window).load(function(){
// this gets dynamic height of your header
var sticky_header = $('header').height();
// apply tha dynamic height to your div after header for margin-top so it not covered by sticky header
$('.sample-content').css('margin-top', sticky_header + 'px' );
});
</script>

I have a header that is not a fixed pixel height - depending on what the other department decides to put in the banner in the content management system, the height of the header will change.
So I did just as #MisterNeutron answer suggested and created a 2nd header (invisible) but my header is pretty Massive, so instead of duplicating the html I just clone the header DOM element with Javascript.
var visibleHeader = document.querySelector('.fixed-top').cloneNode(true);
var invisibleHeader = document.querySelector('.fixed-top');
invisibleHeader.style.visibility = 'hidden';//take up space, but be hidden.
invisibleHeader.style.position = 'relative';//un-fix
document.querySelector('body').insertBefore(visibleHeader, invisibleHeader);
The header it's self is directly inside the body so the html ends up looking like this:
<body>
<div class="fixed-top">
... rest of header html ...
</div>
<div class="fixed-top" style="visibility: hidden; position: relative;">
... rest of header html ...
</div>
... rest of page goes here ...
</body>
Note that if you have any elements with Id's in the header, this will create 2 of the element with same ID, but if you make sure the Real header is Above, I believe when you query for it, it will always grab the one you want.

Related

Dynamically determined height

I am trying to give a div a dynamic height depending on screen size. In the div I have a calendar that has multiple lines of content, that can be shown or not (user's choice), e.i. the calendar's height is not fixed. With that in mind I have div's height set to auto. Which works fine (the height is set according to number of lines in calendar).
The problem arises when I make the browser's height smaller than the amount of height that calendar needs. It becomes a scroll which is not a problem, the position of the scroll is. The scroll is placed on the entire div not on the calendar in the div. The scroll is correct, if the div does not have it's height set, but it does not dynamically shrink to fit only the content (it stays the same height no mater if there is content of not) and I am trying to avoid that.
I suppose the solution is to say that if the div has enough space to use auto and if not it should have the height of it's parent. The min does not take parameters such as auto. I am a bit lost as to how to write code correctly to achieve this preferably using only CSS.
EDIT:
html:
<html>
<body>
<div class = "calendar">
<div class = "content">
<\div>
<\div>
<\body>
<\html>
CSS:
body {height: 100vh; overflow: hidden}
. calendar {overflow-y: auto;}
. content {height: auto;} \\the problem
The height of calendar in JS is set to "parent"
Well, by your answer I am sure you want to make the content responsive. So there is an easy trick or you can say a cheat sheet for your requirement.
Step 1: Include Bootstrap 4 CDN scripts
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">
</script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js">
</script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js">
</script>
Step 2: In your HTML, write a classname as 'form-group' to adjust your calendar's height content as per the screen size.
<div class="form-group">
<div class = "calendar">
<div class = "content">
<\div>
<\div>
</div>
Step 3: Run your project and see how your width of the container adjusts according to the browser when you drag or make it small.
Hope this helps.

How to style a div content after fixed div header with dynamic height

following situation:
<body>
<div style="position:fixed; width:100%">[place holder for header]</div>
<div style="position:relative;width:100%;margin-top:100px">[content]</div>
</body>
I need the header always visible and at the top, so this one should be with position:fixed.
A problem occurs after self adjustments of the header - height. If the header is higher than 100px a part of the content is hidden.
How can I (CSS) dynamically set the start position of the content div regarding the end of the header.
I'm still looking for a CSS only solution, but for the moment here's an idea using just one line of JavaScript – when using jQuery:
JavaScript
$(document).ready(function () {
$('#content').css('marginTop', $('#header').outerHeight(true) );
});
HTML
<body>
<div id="header" style="[…]">[place holder for header]</div>
<div id="content" style="[…]">[content]</div>
</body>
The advantage of using .outerHeight(true) is, that it takes care of borders and margins you may have applied to your header.
CSS only solution (although not super clean) could be to display the same block twice: 1st block "position: fixed", 2nd block "visibility: hidden". Since both would have the same height, the role for the 2nd block would be to push down the page content to the appropriate level.

Absolute positioning: One element expands window, other element doesn't affect it. Both use same code :C

I added two divs to hold background images for decorative purposes - as requested by the artist whom is working with me on a website.
At first, it worked very well. The images were supposed to show on each side of the wrapper div holding the website content - without affecting page width.
Then the organization owning the website got another sponsor, who's logo I had to add to a column on the right. I created a new id for the 5th "button" and created a div for it. Uploading it, I noticed that a scroll bar had suddenly appeared on the bottom of the page, for no apparent reason.
I first suspected the button to be the problem, but eventually found out that the right-most decorative div was bending the page width, despite using absolute positioning. Both of the divs use the same code, only mirrored for left and right. I have no idea what is causing the problem..
(You can see the problem in action while it lasts at www.torucon.no/no/)
Please help me out! Here is the CSS for both of the divs:
#wolf
{
position:absolute;
min-height:500px;
min-width:498px;
left:-293px;
top:150px;
background-image:url('http://www.torucon.no/css/wolf.png');
z-index:-1;
}
#lion
{
position:absolute;
min-height:500px;
min-width:498px;
right:-293px;
top:150px;
background-image:url('http://www.torucon.no/css/lion.png');
z-index:-1;
}
Here is an HTML snippet showing the HTML of the divs:
<div class="wrapper"> <!-- Contains the entire website for structure -->
<div id="wolf">
</div>
<div id="lion">
</div>
((In case you didn't get it: The wrapper div is supposed to be centered, and it is. But when I resize my window, I find that a scroll bar appears long before the wrapper content is even close to the browser window borders. That would be annoying on computers with low resolution or small screens!))
I think what you want is to have the lion and wolf progressively appearing as the user widens the browser viewport, but otherwise partially hidden off to the sides of the wrapper. Correct?
I think you're only safe option to achieve this without triggering the scrollbars you don't like are to combine the images into one and attach them as the background image on the body element of the page.
I believe you're right about using overflow-hidden on the body -- you'd loose the ability to scroll to see overflowed content if the viewport is resized down below the wrapper's width.
I have checked that you posted link http://www.torucon.no/no/ but i coudnt see bottom scroll bar ,
Anyway , Why you cant set background?
<body>
<div class="overlay">
<div class="wrapper">
</div>
</div>
</body>
<style>
body{width:100%; background:---;}
.overlay{width:100%; background:---;}
<style>

Dynamically stretch content based upon number of fixed-width columns

I've worked with CSS enough that I can get columns to work alongside content if I have a set number of columns: I simply define the sidebar(s) in the HTML prior to the content, and specify that they float to the left or right, while giving the content a margin-left or -right such that it doesn't flow into the space below the end of the sidebar.
I have a new challenge though, whereby the number of columns may vary between pages. In my HTML, I don't want to specify the sidebar content prior to the main page content though, which is the only way I know how to do it.
Essentially, I want the HTML to look like this:
<div id="container">
<div id="content">
<!-- Main body content goes here. -->
</div>
<div class="sidebar">
<!-- Sidebar DIV should appear to the right of the content DIV. -->
</div>
<div class="sidebar">
<!--
Another sidebar DIV, with this one *preferably* appearing to the
right of the one above, since it appears lower in the code and is
assuming LTR. I'm open to CSS that makes this sidebar appear to
the left instead of the right, however.
-->
</div>
<!-- Any number of additional sidebar DIV's can appear here. -->
</div>
I'm not sure if I should be trying to float the content/sidebar DIV's, make them position absolute, specify the width, etc. to make the content stretch automatically with the variable number of sidebars. It's probably worth noting that the size of each sidebar will be constant.
div.sidebar {
width: 100px;
}
On final note: if there's an improvement I can make to the HTML that will help, (e.g.: surrounding all the sidebar DIV elements in a parent DIV such as <div id="sidebars">), I'm open to suggestions there as well.
I guess I'll have to accept the fact that this requires HTML tables since no one can offer a CSS solution for this.

How to set div to fill in remaining place taken by the dynamically sized element

I have this code:
<div id="body" style="height: 295px; width: 427px; position: absolute; top: 261px; left: 284px;">
<div id="header">
Some dynamic text<br/>
Some dynamic text<br/>
</div>
<div id="Content">
<textarea id="text" style="width: 100%"> </textarea>
<input type="file" style="width: 100%">
</div>
<div>
</div>
I want to set content div to fill remaining space of its parent. The text is generated server side and it causes the height of the header to change.
The output should look like this: file input should be at the bottom of the content with text input filling remaining of the Content. Content itself fills remaining of the Body, which height is influenced by dynamic text.
I am interested only in CSS solution, as this is easy to do with JS. Also, only width and height of the Body div can be hardcoded.
EDIT:
Some clarifications:
Body is fixed size
Header is dynamic size, can be of any height. If its height > #Body.height, the rest will be cropped and #Content height will be 0. Alternativelly, if possible, #Header could be limited to max half of the #Body with the rest cropped or scrollable.
Content doesn't need any special clarification. It contains of fixed file input and dynamicly height textarea
Thx.
here is a test page showing the html in question:
http://programmingdrunk.com/test.htm
ive taken the liberty to adding colored borders to see what is going on.
edit: now the above link has a solution. it looks a bit strange in firefox, ill see if i can fix that
edit 2:
final solution as can be seen in the link above is this (let me know if i misread your spec)
#text, #Content {
height:86%;
}
I can't understand how such a basic thing as control anchoring (or docking) is not something you can do in CSS. The language that is used for presentation not having fundamental thing is just insane...
Anyway, the above thing probably can not be done in CSS as CSS element is not aware of other elements. Or maybe it can, but such solution will certanly include CSS hacks.
I settled with JQuery LayoutManager framework for now.
Adding float:left to #header will cause #content to fill remaining space, not sure how to achieve the text area though.
Your html makes it really really hard to do what you want. Also, you have not told us what should happen if the content is too high to fit one screen.
Your description makes it sound a bit like you'd want something like:
http://www.sitepoint.com/blogs/2005/10/18/the-catfish-part-1/
In order to get good replies, please consider changing of the html structure.
EDIT:
Okay, what you want is just not doable if you want ie to behave. If we drop ie or no-js limitations, then there is a small chance in doing this with table-style layouts. But this is really weird request and you should consider really hard why do you want to do it like this at all.

Resources