I have a fixed navigation bar on my website that stays at the top with links that take me to different sections further down the page. However, because my fixed nav bar has a height of 40px, the beginning 40px of every section is covered up. How would I offset where my links take me by 40px using either HTML or CSS?
Thanks.
You might try absolutely positioning "dummy" anchors 40 pixels above the top of each section. You can give them zero width/height and hidden visibility to ensure that these anchors don't affect how your page is displayed. When the user clicks one of the links in your fixed navigation bar, the window will scroll to the top of the dummy anchor, 40 pixels above the beginning of its actual section.
Example HTML:
<div class="navbar">
Anchor 1
Anchor 2
Anchor 3
</div>
<div class="section">
<span id="anchor1" class="anchor"></span>
Section Content
</div>
<div class="section">
<span id="anchor2" class="anchor"></span>
Section Content
</div>
<div class="section">
<span id="anchor3" class="anchor"></span>
Section Content
</div>​
Example CSS:
body {
padding-top: 40px;
}
.navbar {
position: fixed;
width: 100%;
height: 40px;
top: 0;
left: 0;
z-index: 10;
border-bottom: 1px solid #ccc;
background: #eee;
}
.section {
position: relative;
}
.anchor {
display: block;
position: absolute;
width: 0;
height: 0;
z-index: -1;
top: -40px;
left: 0;
visibility: hidden;
}
For a working example, see http://jsfiddle.net/HV7QL/
Edit: CSS3 also includes the :target pseudo-class, which applies to an element whose id has been referenced by the href of a link in the document, or the hash value of the URL. You can apply a 40-pixel padding to the top of the :target that will be applied only to the section the user selects from the fixed navbar.
Example CSS:
.section:target {
padding-top: 40px;
}
This is semantically cleaner than the method described above, but won't work on older browsers.
Working example: http://jsfiddle.net/5Ngft/
I just happened to stumble across this problem myself today so I had been thinking about it for a bit already, but I think I just found a solution:
Add a padding-top: 40px; margin-top: -40px to the element that you want to jump to. The negative margin cancels the padding, but the browser still thinks that the top of the element is 40px higher than it actually is (because in fact it is, only the content of it starts lower).
Unfortunately, this might collide with already set margins and paddings, and if you're using a background on the targeted element it's going to mess it all up.
I'll see if I can work around that and post a jsfiddle, but in the meantime here's a basic answer at least :)
edited: I thought I had a solution for the background, but it didn't work. Removed again.
final edit:
It does kind of work if you know the background color of the wrapping element. In my example I know the text is on a white background, but the titles have a silver background. To prevent the title from having a background on the extra padding we set, instead I put it on a pseudo-element before it:
#three:before {
content: " ";
background: white;
display: block;
margin-top: -40px;
padding-top: 40px;
}
This way the extra padding has a white background again, but this only works if you already know what background it needs. Setting it to transparent for example will show the underlying background of the title itself, not of the article.
jsFiddle: http://jsfiddle.net/Lzve6/
Heading one is the default one you're having problems with.
Heading two is my first solution, guaranteed to work on almost all browsers
Heading three is using the :before pseudo-element, might not work on older browsers.
Related
On my site http://richardclifford.net/, whenever a user clicks the one-page #id elements it goes to the very first piece of content the and ignored all the container padding and h2 margin-top to look like this
I'd want it to scroll to include the padding or have an offset like this.
I've add an offset on my scrollspy but that is not fixing it and not sure how I can fix this.
add margin-top: -50px;padding-top: 50px; to target id it works
#work,#about,#contact,#copyright{
margin-top: -50px;
padding-top: 50px;
}
You can use margin-top and padding-top for this with out affecting to the front side of the website. Try to add -50px to margin top and 50px to padding top. This will fix your issue.
One common way is to add invisible pseudo elements to the original target elements of the links via CSS, like this:
#work::before {
display: block;
content: " ";
margin-top: -60px;
height: 60px;
visibility: hidden;
pointer-events: none;
}
This will "extend" the element with that ID in a way which causes the anchor to be 60px above the main element (can be any value), without causing any other visible changes.
For a simple landing page I wanted to let some text box overlap an header image. To make it simple, I just have a structure like:
<header>
<img src="path/to/img.png" />
<h1>Awesome headline</h1>
</header>
All elements are set to display:block and the h1 is dragged inside the image with a negative margin. I also gave the headline some padding and background:white.
Now the problem: The headline text is shown on top of the image but the background colour is behind it! You can see an example here: https://jsfiddle.net/cv12evLn/
My guess is, that a browser renders all sibling blocks in layers, starting with all backgrounds and borders, then rendering images (img-tags) and finally text on top of everything else.
Is that right? And why the actual… I mean, that seems crazy unexpected to me.
To solve the issue, I've put the headline in a wrapper and set this to position:absolute. See here for a live example: https://jsfiddle.net/f5sd1u6o/
Use position:relative rather than negative margin. Then the z-index works automatically.
#container {
width: 500px;
height: 300px;
margin: auto;
}
#container img {
display: block;
width: 100%;
}
#container h1 {
display: block;
width: 50%;
height: 1em;
margin: auto;
padding: .5em 1em 1em;
font-size: 3rem;
background: yellow;
text-align: center;
border: 1px solid red;
position: relative;
top: -4.6rem;
}
<div id="container">
<img src="//placekitten.com/500/300">
<h1>
headline
</h1>
</div>
To get the Z-index to work, you need to apply position:relative anyway but you can still use negative margin if that is a design requirement.
JSfiddle demo (with negative margin)
Basically, backgrounds are rendered first before anything else (as I understand it) so they always come at the bottom of the stacking order. You just need to create a new stacking context and changing the position property does that.
As it happens so does changing the opacity of the element so a quick fix is to set opacity:.9999;
JSfiddle Demo (opacity 'hack')
I apologize if this has been answered time and time again. I remember searching thoroughly for an answer a couple years ago when I first wrote up my website script, but I couldn't ever find one. The same for now.
Recently I reworked my website's script so I can host it onto Weebly. Here is one of the four pages of my site that I need help with. As you can see, the images that pop up when the thumbnail is hovered over are absolutely positioned. For most computer resolutions and/or browsers, this will have the image appear out of the designated box.
How could I position them to the inner top left corner of the div? Or better yet, horizontally and vertically centered within it?
<section id="Sizes" style="float: left">
<a href="#Space">
<img class="Small" src="/files/theme/SampleD_Fun_Icon.png" width="150" height="150" alt="Sample 1: Day of Fun" />
<img class="Large" src="/files/theme/SampleD_Fun.png" width="150" height="150" alt="Sample 1: Day of Fun" />
</a>
...
</section>
<a id="Space"></a>
<span class="Popup">Hover over thumbnail to display sample artwork.</span>
<br style="clear: left" />
a:hover img.Small
{
border: 5px solid #21568b;
margin: 10px;
text-decoration: none;
}
section#Sizes a img.Large
{
border-width: 0;
height: 0;
left: 438px;
position: absolute;
top: 326px;
width: 0;
}
section#Sizes a:hover img.Large
{
height: 526px;
left: 438px;
position: absolute;
top: 326px;
width: 520px;
}
.Popup
{
border: 3px solid;
float: left;
height: 272px;
margin: 8px 20px 0px 0px;
padding-top: 254px;
text-align: center;
width: 520px;
}
Thank you for your time. :)
Your whole design is a bit fragile, and I wouldn't recommend building this this way in the first place, but you're looking for practical answers, so here's the smallest change I can think of that fixes your problem:
1) Add this to your style sheet:
body { position: relative; }
2) On line 40 from your main_style.css, change top: 326px to top: 316px and left: 438px to left: 428px, so that it becomes like this:
section#Sizes a:hover img.Large {position: absolute; top: 316px; left: 428px; width: 520px; height: 526px;}
How does that work?
Your images are place using absolute positioning. By default, that works relative to the viewport (the window). But by turning the body into position relative, it becomes a containing block, and position absolute is relative to the nearest containing block ancestor.
So now, your images are fixed within the body element, instead of being fixed relative to the window. Since the margins of the body element is what's changing size when you resize the window, that makes the various pieces of your content fixed relative to each other. You then just need to remove 10px from the top and left side, since that's the size of the border of your body element, and we're now measuring from inside the border.
TLDR: You can't do this in pure CSS.
You can easily position the image inside the container div if you place the image element inside the div element, and then use absolute positioning like top: 0; left: 0; (or with a number of other methods). But then you'd need JavaScript to correlate the hovered thumbnail with the popup full-size image.
Alternatively, you can have the full-size image be nested in the thumbnail element (like you currently have), but then you'd need JavaScript to position the full-size popup image inside the container div.
Of the two alternatives, I recommend the first: put all the popup images inside the target container, and use JavaScript to show or hide them when a thumbnail is hovered. Correlating the thumbnail and the full size image via JavaScript is going to be easier then writing positioning code.
I see you're using jQuery already so why not do something like this?
$('.Small').on('mouseover', function(){
$('.Popup').empty().html($(yourtarget).attr('img' , 'src'));
});
$('.Small').on('mouseout', function(){
$('.Popup').empty().html('Hover over thumbnail to display sample artwork.');
});
Just because everyone was saying it can't be done with pure css, I wanted to demonstrate that it can, and it is even quite easy. Have a look at the folowing example:
http://jsfiddle.net/aafa2zp5/
<div id='images-wrapper'>
<ul>
<li>
<img class='small' src='http://placehold.it/50/ff0000'/>
<img class='big' src='http://placehold.it/300/ff0000'/>
</li>
<!-- and some more similar thumb / image groups -->
</ul>
<div class='preview-area'></div>
</div>
CSS (or the relevant part at least)
#images-wrapper {
position: relative;
}
.big {
display: block;
position: absolute;
top: 54px;
right: 54px;
opacity: 0;
transition: opacity .5s;
}
.preview-area {
width: 350px;
height: 350px;
border: 4px solid blue;
position: absolute;
top: 21px;
right: 21px;
}
li:hover .big {
opacity: 1;
}
The key is to set a position relative to the wrapper (and keep all of the descendants as their default static). Then you can use this to position the preview area and the big images against by setting them to postion absolute and carefully calculating the correct postion. I even added a cross fade, just because it is so easy, but you could just as well work with display block / none if you prefer.
For smaller screens you may want to alter the dimensions and positioning inside a media query, but it still should be doable (though depending on the hover state is perhaps not the best idea on a touch device)
I hope you get the idea and you can figure out how to apply this technique to your own site. Feel free to ask if you want me to explain further or when you get stuck.
I have a website here with a sidebar, but I want the sidebar to be hidden until the user clicks on a menu button. Anyways, my .sidebar is on z-index: 0; while my .page-content is on z-index: 1;. Why is the sidebar not hidden when I load the webpage? I have nothing in my page-content except for a <h1> for testing purposes.
Here is my HTML file:
<!DOCTYPE html>
<head>
</head>
<body>
<div class = "page-wrapper">
<div class = "page-content">
<h1>Test</h1>
</div>
<div class = "sidebar">
<ul>
<li>#</li>
<li>#</li>
<li>#</li>
<li>#</li>
<li>#</li>
</ul>
</div>
</div>
</body>
</html>
And here is my CSS file:
h1 {
/* Just to centre my text */
position: relative;
left: 50%;
}
.page-content {
position: relative;
z-index: 1;
}
.sidebar {
position: fixed;
left: 0px;
top: 0px;
bottom: 0px;
width: 120px;
padding: 30px;
background: #333;
z-index: 0;
}
So why isn't my sidebar being hidden when I load the webpage? When I load this, I can see the sidebar and the "Test" text both.
EDIT:
I see many of you have said that the z-index is not for hiding stuff. I am not trying to hide the sidebar. When the user clicks on the menu button, I want the page to slide over to reveal the sidebar, hence the reason I am using the z-index and not display: none;.
EDIT:
Some of you have said that this is a duplicate from another question, but when you read my comments, please realize that the question I am asking, is quite different. I am going to try to explain what I am attempting to do here as simply as I can. I have a website, where a user clicks on the menu bar, the entire website transitions 180px to the right, thus revealing the sidebar that is fixed underneath. You guys mentioned that my .page-content needs a background, but like someone else said, it only takes up my background as big as the objects inside are. How or where can I set a background that will move, yet still cover the sidebar completely?
Firstly, your z-index IS working.
z-index is not responsible for making an element visible or not. (For that, you can use the opacity,visibility, or display properties.
z-index can be used to position elements behind other elements with opaque backgrounds, which may make them appear hidden (pun intended), but rest assured, the element is still there.
Your CSS has no elements with opaque backgrounds with z-indicies higher than 0 that sit on top of .sidebar, so that's why you see it.
Your sidebar is not hidden because your .page-content doesn't have a background. Put a background and add this CSS:
.page-content{
background: #fff;
height: 100%;
width: 100%;
}
This way, you'll be able to slide it to then side afterward.
Add background to .page-content you will see the z-index's effect.
A better approach would be to hide the side bar with left property as some negative value, for example -100px as below.
.sidebar {
position: fixed;
left: -100px;
top: 0px;
bottom: 0px;
width: 120px;
padding: 30px;
background: #333;
z-index: 0;
}
and when the user clicks the menu icon set left: 0px using javascript.
I have seen the layout similar to the image below used on some sites before and I really like the design but don't exactly know how to implement the overlapping image (Profile Image). I am using bootstrap if that helps. Any ideas?
Thanks!
I can see three ways to do this generally.
position: absolute
You could give the image or the image's wrapper the attribute of position:absolute and giving its container (in your example the green box) position:relative. Then you would apply top: -100px or whatever and a left attribute of left: 100px or whatever. This gives the effect of the image being out of flow, aligned to the left and offset by 100px, and 100px offset from the top of the green container. The disadvantage of this approach would be that any body content in your green container could appear under the image.
position: relative
This is the same approach as the first one with the exception of how the image flows in the document. Instead of giving the image position:absolute, you would give it position:relative. Relative works differently from absolute. instead of being x and y coordinates of the parent container, it's just shifted by however much you give as a value for top and left. So in this case, you would apply top:-100px and just leave the other directional values as default. this would shift your element by that amount but also leave its original spot in the document flow. As such you end up with a gap below the image that other content will flow around.
negative margin
I honestly would prefer this method in your case. In this method, you can give the image a negative margin (e.g. margin-top:-100px). This will offset the image, collapse the area below the image, and it will still retain some of its flow in the document. This means that the content of the green container will flow around the image but only around the part that is still inside the container. It won't have a ghost area that content flows around like with relative positioning, but it also doesn't entirely take the image out of flow like absolute positioning. One thing to keep in mind, however, is that if you try to use overflow of any kind other than the initial value, it will cause undesirable effects to your image.
Demo
Here's a quick little demo demonstrating all three methods in a simple use case: http://jsfiddle.net/jmarikle/2w4wqfxs/1
The profile image can be set with position: absolute; top: 20px; left: 20px, or something like that to keep in from taking up space in the flow of the page.
make the html element that holds the header image "position:relative". Then put the header image and the profile image in that element. then make the profile image "position:absolute" and utilize "top: XXpx" depending on how far you want it from the top of the header element. Same for "left".
see fiddle here
<div class="header">
<img src="" alt="my image" class="floatdown">
this is my header, image could go here too
</div>
<div class="body">
this is my body content
</div>
.header {
position: relative;
width: 100%;
height: 150px;
border: 2px solid #000;
text-align: right;
}
.body {
position: relative;
width: 100%;
border: 2px solid #000;
height: 500px;
text-align: right;
}
img {
width: 90px;
height: 90px;
border: 2px solid #ddd;
}
.floatdown {
position: absolute;
top: 100px;
left: 20px;
}
You can use the float property on your profile image to take it out of the "flow" of the document, and play with the margins to place it properly.
CSS :
#profile-image{
width: 100px;
height: 100px;
float: left;
margin: 100px;
}
The marginis used to push it down and place it properly.
You can see an example of this in a Fiddle : http://jsfiddle.net/y706d77a/
I wouldn't recommand using position: absolute as you can get very strange results with different resolutions. I would only use that as a last resort.
This can be done many ways.
Anytime you see something like that on the web you can just use your inspector or firebug and see how they are doing it to get some ideas.
It wouldn't hurt to do some research on the web about CSS positioning.
http://www.w3schools.com/css/css_positioning.asp
Another great site.
http://css-tricks.com/
I just finished it.
Here is a codepen link:
http://codepen.io/anon/pen/zxYrxE
HTML:
<div class="main-container">
<div class="header">
<p>This is the header div</p>
</div>
<div class="profile">
<p>Profile</p>
</div>
<div class="content">
<p>Some dummy content div</p>
</div>
</div>
CSS is to big to be pasted here, so just open the link.
Put the profile image in the header, make the position: absolute; and the image position: relative;, and give it a negative bottom value that's half the height of the image, and set left to position it horizontally to taste.
HTML
<header>
<img class="profile">
</header>
<div>Content</div>
CSS
header, div{
min-height: 110px;
background: darkgray;
}
header{
position: relative;
background: gray;
}
img{
position: absolute;
bottom: -50px;
left: 100px;
}
http://jsfiddle.net/dekqn84c/