fixed menu on a certain part of the page - html

how can i make a menu position to the top of my page while scrolling. well i can do that on my header. but not on a certain part of the page .let's say my other menu is position on a 980px height of the page . if i try to use position:fixed it will just hide the menu. even if i use z-index. here's the visual:
+________________________+
| HEADER MENU <--- Fixed menu - stays at top even when scrolling.
+¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬+
| CONTENT BEGINS |
| HERE |
| |
| OTHER MENU | <---- This must stay on the top when i hit this menu
| | and stay while scrolling
| |
| |
| |
| |
+¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬+

Here is a codepen with an example of position: sticky and a basic jquery example. Remember there are some support issues but you're mostly okay at this point. But it is something to look into if you decide to use sticky.
https://codepen.io/anon/pen/WZGxrm?editors=1111 (remove comment syntax to show one option or the other)
#otherMenu {
position: sticky;
top: 50px;
}
Adds 50 to account for the height of the header:
var menu_position = $("#otherMenu").offset().top;
$(window).on('scroll', function() {
if (($(document).scrollTop() + 50) >= menu_position){
$("#otherMenu").css({"position":"fixed", "top":"50px"});
} else { $("#otherMenu").css({"position":"static", "top":"auto"});
}
});

be sure that there's no overflow:hidden on the header container

Related

CSS Fixed Header, scrolling body with left sidbar/content/right sidbar and footer

I have spent the last week trying to tweak a layout and keep rebuilding from scratch without success, so asking for help.
I'm trying to achieve
1. a fixed header which does not scroll and always viewable
2. a main area with left sidebar (nav) / content / right sidebar (ads) which scroll
3. a footer which is only visible when scrolled to the bottom
My vision is :
|--------------------------------|
| header (always viewable ) |
|--------------------------------|
|| L | | R ||
|| e | | i ||
|| f | | g ||
|| t | | h ||
|| | | t ||
|| S | Content Area | ||
|| i | | S ||
|| d | | i ||
|| e | | d ||
|| b | | e ||
|| a | | b ||
|| r | | a ||
|| | | r ||
||------------------------------||
|| footer visible at end scroll ||
||------------------------------||
The basic structure of the HTML has a few more divs than could be done with but I'm planning for maximum flexibility ( and problably creating problems)
<div class="site-container">
<div class="site-header">
SITE HEADER
<!-- HEADER CONTENT GOES HERE -->
</div> <!-- site-header -->
<div class="site-content">
SITE-CONTENT (with reduced padding not visible )
<div class="content-main">
<div class="content-main-left">
CONTENT-MAIN-LEFT ( Navigation )
</div>
<div class="content-main-middle">
CONTENT-MAIN
<!-- MIDDLE COLUMN CONTENT GOES HERE -->
Lorem ipsum dolor etc ...
</div>
<div class="content-main-right">
CONTENT-MAIN-RIGHT ( Ads )
</div>
<div class="content-footer">
CONTENT-FOOTER
</div>
</div> <!-- content-main -->
</div> <!-- site-content -->
</div> <!-- site-container -->
However, the more I play with it, the more messy and unworkable it gets.
I'm currently stuck in the loop of fixing one problem while creating another.
Here's my JSFiddle version
Any help is greatly appreciated.
Thanks
You'll want to work out how you want that central column of text to work.
If you have a fixed width container, you could float the elements, and give them a fixed width.
Many grid systems like Bootstrap or Base use floated columns to lay things out. They also use media queries in CSS to cater for different screen sizes.
If you want a layout that has fixed-width columns and a variable width central column, and you did want to do things yourself, you can position things absolutely inside your main content holder.
Check out an updated JSFiddle to see how you could use position:absolute to lay things out.
There's a few updates to your HTML in there, but a CSS layout like this:
.site-header {
position: fixed;
top:0px;
width: 100%;
height: 50px;
padding:20px 0;
z-index:2;
}
.content-main-left {
width:100px;
min-height:200px;
position:absolute;
left:0;
background-color: tan;
}
.content-main {
padding:0 120px 0 120px; /* padding to make room for the left and rigth columns */
}
.content-main-right {
width:100px;
min-height:200px;
position:absolute;
right:0;
top:0;
background-color: rosybrown;
}
.site-content {
position:relative;
top:120px;
}
.content-footer {
position: relative;
left:0;
height: 60px;
width: 100%;
}
It's always good to strip things back and get one thing working at a time. There were a few lines in that probably weren't helping:
The left column <div> wasn't closed, so your main content was sitting inside that <div>
It looks like you've tried to close the 'site-header' tag at the bottom of the content.
Putting a <div> around your left, center and right columns will help you place a footer at the bottom of all three sections. I've renamed this "site-footer"
Hope this helps!
I found, that if my left / right sidebars grow in length then the bottom of the page starts to get messy.
i.e. jsFiddle
I spent a lot of time playing around but couldn't get it working.
I did not know about the calc option, which I think enables me to have an easier to manage (for a CSS noob like me) solution as I can stay away from absolute positioning.
The result is jsFiddle.
I'd love the option of getting the left/right bars to grow to the bottom using something like
height: calc(100% - 100);
but it doesn't seem to work, and presumably I'd have to delve back into the world of absolute to get it to work.
Again, thanks for the help.

How to set dimension (width) in a div box in this situation

I want to set the width (in pixels) of the orange box.
You can see my page on this: live link
<div align="center" class="copyright" style="border: thin solid #F48C13"><p> </p>
<p><strong>Accesso a MpcPanel</strong></p>
Simply define width property in your stylesheet for the class copyright
.copyright {
width: 100px;
}
Ex.: http://jsfiddle.net/wm754s90/3/
Edit:
For Inline style (that's without modify the css file, and including the style directly in the element)
The style attribute of the div.copyright need to be edited.
Just add width property alongside to border.
<div align="center" class="copyright" style="width: 100px; border: thin solid #F48C13;">
<!-- /* div content */ -->
</div>
You can add as many as you want (semicolon separated) but keep in mind the readability of the code (for that are external CSS files, among many other benefits)
I will recommended to you (if you can of course) to create your own css file and include there all the modifications you want. Will be a good starting point to learn css and how it's work.
Edit 2:
Worth to mention that both properties (width & border) might conflict.
Width prop. do not include the border size.
Ex.
.copyright {
width: 100px;
border: thin solid #F48C13;
}
---------------------
| ----------------- |
| | | |
| | div content | |
| | | |
| ----------------- |
---------------------
| |
|<------------->| -----> A) div width = 100px
| |
| | | |
<-> <-> -----> B) div border size = 1px
\ / (the size you enter is for each side)
border size ("thin" in border size is equal to 1px)
| |
| |
|<----------------->| -----> total/final div width = 102px
B + A + B
1 + 100 + 1 = 102px
or use 98px as width... 1 + 98 + 1 = 100px
Please refer to this box-sizing article for a better and more accurate explanation (including how to avoid/solution)
If I understood your question correctly, you wish to make the border of the orange box to be thicker? If so, you would change the border CSS property "thin" to a pixel value, like so:
style="border: 4px solid #F48C13"
If not, I apologise, I could not comment yet to ask this clarification.

Avoiding duplicated content for responsive page

I am currently working on a project dealing with responsive design, and the whole layout should be achieved using HTML and CSS. I know its possible to move content from one column layout to another, without duplicating content, using java script but is the same achievable using HTML and CSS?
Take for example the following which would render like this on the desktop design
--page-------------------
| -------- -------- |
| |div 1 | | div 2| |
| -------- -------- |
-------------------------
But then the designer has moved div1 to below div2 on the mobile design.
--page--------
| -------- |
| |div 2 | |
| -------- |
| -------- |
| |div 1 | |
| -------- |
--------------
Obviously the natural way the block level elements will stack is the opposite way around.
--page-------------------
| -------- -------- |
| |div 1 | | div 2| | <--- shown on desktop
| -------- -------- |
| -------- |
| |div 1 | | <--- hidden on desktop
| -------- |
-------------------------
--page--------
| -------- |
| |div 1 | | <--- hidden on mobile
| -------- |
| -------- |
| |div 2 | | <--- shown on mobile
| -------- |
| -------- |
| |div 1 | | <--- shown on mobile
| -------- |
--------------
Using the above, the content of div1 is duplicated. Is this bad for SEO? Clearly it's not optimal as the content appears twice in the DOM etc, so speed is affected (albeit possibly negligible).
Are there any other solutions which I could implement which aren't javascript based which might alleviate the issue?
Any advice would be much appreciated.
Duplicate content for SEO is a real problem with responsive pages if you are hiding and unhiding elements. The code is still rendered in the DOM and if the search engines can see the code (even if the user cannot see the output) it will still count against you. None of the answers above provide a real solution for this, and to be quite honest I can't either at this point.
I am moving towards actually removing elements with javascript from the DOM, but that gets extremely messy and is not ideal either.
The media query answer above will not change the fact that you still have HTML outputting into the DOM with duplicate content.
The CSS order property can be used to reorder flex children.
Bootstrap4 has introduced some (responsive) flex utilities that you can use to change the order of flex children.
<div class="row">
<div class="col-sm-6 order-2 order-sm-1">div 1</div>
<div class="col-sm-6 order-1 order-sm-2">div 2</div>
</div>
Consider the bootstrap-based snippet above. div 1 and div 2 appear in source order for devices that are sm and higher (md, lg, xl) whereas div 2 appears before div 1 on xs devices.
If the divs are a predictable size (e.g. 50em) you could just offset them with position: relative and negative top values. This will let you give the appearance of a reordered flow without changing markup.
For example:
#div1 {
float: left
clear: both;
height: 50em;
position: relative;
top: 50em;
}
#div2 {
float: left
clear: both;
height: 50em;
position: relative;
top: -50em;
}
Place that inside a media query and it will give you the result you want.
Duel content is an issue best avoided, of course. And we should always create elements which can be any height, to allow for CMS content.
I'd suggest the mark-up order should be:
--page--------
| -------- |
| |div 2 | |
| -------- |
| -------- |
| |div 1 | |
| -------- |
--------------
... as the designer specifies in the mobile layout. Width tends to be more knowable than height, so on desktop, you could do "the old switcharoo" to change their positions. Clearfix is implied. For example on desktop:
.div1, .div2 {
float: left;
position: relative;
width: 200px;
}
.div2 {
right: -200px;
}
.div1 {
left: -200px;
}
... which should give you this layout:
--page-------------------
| -------- -------- |
| |div 1 | | div 2| |
| -------- -------- |
-------------------------
(I've not checked this code - in all probability I've got my right and left mixed up)
Does this make sense?
I know I'm late, but I hope this helps somebody else.
I would solve it by thinking it mobile-first. #div1 should be the first one shown in mobile resolutions, and #div2 the second one.
Then I would make them both float right, so the "first one" will be shown in the right when desired.
Here is an example (better see it in full page to see responsiveness):
* { box-sizing: border-box; }
div { border: 1px solid gray; }
#div1 { background: lightblue; }
#div2 { background: yellow; }
#media (min-width: 768px) {
div {
display: inline-block;
width: 50%;
float: right;
}
}
<div id="div1">
<p>This div will be shown on top on mobile resolutions, and will be in the right in any other resolution!</p>
<p>We could say it will be a main content holder in mobile, and secondary in desktop</p>
</div>
<div id="div2">
<p>This div will be shown on bottom on mobile resolutions, and will be in the left in any other resolution!</p>
<p>We could say it will be a main content holder in desktop, and secondary in mobile</p>
</div>
You can use CSS Flexbox's order property for doing this: Suppose your markup is:
.my-flex-container {
display: flex;
}
/* change order on devices <= 768px */
#media (max-width: 768px) {
.my-flex-container {
flex-direction: column;
}
#div1 {
order: 2;
}
#div2 {
order: 1;
}
}
<div class="my-flex-container">
<div id="div1">Content of div1</div>
<div id="div2">Content of div2</div>
</div>
Hope it will work fine for you

How do I bottom-align grid elements in bootstrap fluid layout

I have a fluid layout using Twitter's bootstrap, wherein I have a row with two columns. The first column has a lot of content, which I want to fill the span normally. The second column just has a button and some text, which I want to bottom align relative to the cell in the first column.
Here's what I have:
-row-fluid-------------------------------------
+-span6----------+ +-span6----------+
| | |short content |
| content | +----------------+
| that |
| is tall |
| |
+----------------+
-----------------------------------------------
Here's what I want:
-row-fluid-------------------------------------
+-span6----------+
| |
| content |
| that |
| is tall | +-span6----------+
| | |short content |
+----------------+ +----------------+
-----------------------------------------------
I've seen solutions that make the first span an absolute height, and position the second span relative to it, but a solution where I didn't have to specify the absolute height of my divs would be preferred. I'm also open to a complete rethink of how to achieve the same effect. I'm not married to this use of the scaffolding, it just seemed to make the most sense to me.
This layout as a fiddle:
http://jsfiddle.net/ryansturmer/A7buv/3/
This is an updated solution for Bootstrap 3 (should work for older versions though) that uses CSS/LESS only:
http://jsfiddle.net/silb3r/0srp42pb/11/
You set the font-size to 0 on the row (otherwise you'll end up with a pesky space between columns), then remove the column floats, set display to inline-block, re-set their font-size, and then vertical-align can be set to anything you need.
No jQuery required.
Please note: for Bootstrap 4+ users, please consider Christophe's solution (Bootstrap 4 introduced flexbox, which provides for a more elegant CSS-only solution). The following will work for earlier versions of Bootstrap...
See http://jsfiddle.net/jhfrench/bAHfj/ for a working solution.
//for each element that is classed as 'pull-down', set its margin-top to the difference between its own height and the height of its parent
$('.pull-down').each(function() {
var $this = $(this);
$this.css('margin-top', $this.parent().height() - $this.height())
});
On the plus side:
in the spirit of Bootstrap's existing helper classes, I named the class pull-down.
only the element that is getting "pulled down" needs to be classed, so...
...it's reusable for different element types (div, span, section, p, etc)
it's fairly-well supported (all the major browsers support margin-top)
Now the bad news:
it requires jQuery
it's not, as-written, responsive (sorry)
You can use flex:
#media (min-width: 768px) {
.row-fluid {
display: flex;
align-items: flex-end;
}
}
You need to add some style for span6, smthg like that:
.row-fluid .span6 {
display: table-cell;
vertical-align: bottom;
float: none;
}
and this is your fiddle: http://jsfiddle.net/sgB3T/
Here's also an angularjs directive to implement this functionality
pullDown: function() {
return {
restrict: 'A',
link: function ($scope, iElement, iAttrs) {
var $parent = iElement.parent();
var $parentHeight = $parent.height();
var height = iElement.height();
iElement.css('margin-top', $parentHeight - height);
}
};
}
Just set the parent to display:flex; and the child to margin-top:auto. This will place the child content at the bottom of the parent element, assuming the parent element has a height greater than the child element.
There is no need to try and calculate a value for margin-top when you have a height on your parent element or another element greater than your child element of interest within your parent element.
This is based on cfx's solution, but rather than setting the font size to zero in the parent container to remove the inter-column spaces added because of the display: inline-block and having to reset them, I simply added
.row.row-align-bottom > div {
float: none;
display: inline-block;
vertical-align: bottom;
margin-right: -0.25em;
}
to the column divs to compensate.
Based on the other answers here is an even more responsive version. I made changes from Ivan's version to support viewports <768px wide and to better support slow window resizes.
!function ($) { //ensure $ always references jQuery
$(function () { //when dom has finished loading
//make top text appear aligned to bottom: http://stackoverflow.com/questions/13841387/how-do-i-bottom-align-grid-elements-in-bootstrap-fluid-layout
function fixHeader() {
//for each element that is classed as 'pull-down'
//reset margin-top for all pull down items
$('.pull-down').each(function () {
$(this).css('margin-top', 0);
});
//set its margin-top to the difference between its own height and the height of its parent
$('.pull-down').each(function () {
if ($(window).innerWidth() >= 768) {
$(this).css('margin-top', $(this).parent().height() - $(this).height());
}
});
}
$(window).resize(function () {
fixHeader();
});
fixHeader();
});
}(window.jQuery);
Well, I didn't like any of those answers, my solution of the same problem was to add this:<div> </div>. So in your scheme it would look like this (more or less), no style changes were necessary in my case:
-row-fluid-------------------------------------
+-span6----------+ +----span6----------+
| | | +---div---+ |
| content | | | & nbsp; | |
| that | | +---------+ |
| is tall | | +-----div--------+|
| | | |short content ||
| | | +----------------+|
+----------------+ +-------------------+
-----------------------------------------------
.align-bottom {
position: absolute;
bottom: 10px;
right: 10px;
}

Scrollbar resizing the page

Let's say I have a static webpage and the whole page is wrapped, let's say inside a width of 700px, now if the content of the page is too long then (obviously) a scrollbar appears. BUT the appearance of the scrollbar moves everything to the left of like a few pixels (the ones needed to fit the scrollbar on the right side of the page). What I'd like to do is to remove this "moving" effect, so that if a scrollbar is needed this doesn't affect the content of the page in any way.
I don't know if I made myself clear.
let's say that this is a webpage:
| .........contentcontent ........ |
| .........contentcontent ........ |
| .........contentcontent ........ |
| .........contentcontent ........ |
| .........contentcontent ........ |
| .........contentcontent ........ |
| .........contentcontent ........ |
and this is how it looks with the scrollbar:
| .....contentcontent .......... | |
| .....contentcontent .......... | |
| .....contentcontent .......... | |
| .....contentcontent .......... | |
|......contentcontent .......... | |
| .....contentcontent .......... | |
| .....contentcontent .......... | |
but I'd like to have something like this:
| .........contentcontent ...... | |
| .........contentcontent ...... | |
| .........contentcontent ...... | |
| .........contentcontent ...... | |
| .........contentcontent ...... | |
| .........contentcontent ...... | |
| .........contentcontent ...... | |
dots represent whitespace, content represent the webpage content and the column on the right represents the scrollbar.
You can set overflow-y: scroll as rule for your body. This will always display a vertical scrollbar which is disabled unless the content is long enough to be scrolled. This way the content won't shift to the left when its long enough that you can actually scroll and no scripting is needed to make this work.
if you are not need scrollbar at all, you can use this:
body {
overflow-y: hidden;
}
UPD. so if you need scrollbar to scroll content, but want to hide it, you can use the following method (demo on dabblet.com):
css:
body {
overflow: hidden;
}
#fake_body {
position: absolute;
left: 0;
top: 0;
right: -32px;
bottom: 0;
overflow-y: scroll;
}
html:
<div id="fake_body">
<ul>
<li>content content content #01</li>
<li>content content content #02</li>
<li>content content content #03</li>
…
<li>content content content #55</li>
</ul>
</div>
The following is not supported well across browsers, as per
MDN docs, however I think you may find it interesting.
overflow-y: overlay;
In browsers that support the property, such as Google Chrome, this will put the scrollbar on top of your content instead of shifting your content over when a scrollbar is needed. You could then add a sufficient amount of padding so that your content is never covered up by it.
It seems this property is not popular, and even browsers that support it now are planning to drop support for it. I don't understand why, because it certainly has its uses.
I had the same problem and only solution using JS/jQuery was enough good for me.
I used link to Detect if a page has a vertical scrollbar? provided before and those links: http://davidwalsh.name/detect-scrollbar-width, http://api.jquery.com/css/#css2, Center a position:fixed element for generating the following code.
css:
body {
position: absolute;
left: 50%;
margin-left: -400px;
width: 800px;
height: 100%;
}
.scrollbar-measure {
width: 100px;
height: 100px;
overflow: scroll;
position: absolute;
top: -9999px;
}
JS:
$(document).ready(function() {
// Check if body height is higher than window height :)
if ($(document).height() > $(window).height()) {
// Create the measurement node
var scrollDiv = document.createElement("div");
scrollDiv.className = "scrollbar-measure";
document.body.appendChild(scrollDiv);
// Get the scroll bar width
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
// Delete the DIV
document.body.removeChild(scrollDiv);
// Change margin-left parameter for #container for preventing shift caused by scroll bar
var current_margin_left_px = $("#container").offset().left;
var current_margin_left = parseInt(current_margin_left_px, 10);
var changed_margin_left = current_margin_left + scrollbarWidth/2 + "px";
$("#container").css("margin-left", changed_margin_left);
}
});
In case of flexible body width some more code has to be added.
you can check if the screen has a scroll bar. if true than you could margin the content to the right maybe this link will help you : Detect if a page has a vertical scrollbar?
overflow-x: hidden;
in the body CSS code, HELPED AlOT! Damn, took me 45mins to surf around for a simplistic answer.
what went wrong? ...I had an with a hover=show image thing going on. I resized all the images correctly; when I refreshed the page, the scrollbar had way to much play room!.....So i put an overflow-x into each and every div tag, (each div tag assigned to individual list item), and nothing happened!
solution: The code was correct, but the placement needed to be in the body tag itself. not the individual div tags. Damn.....thankz