What I want
two div : A page body (1) and a background block (2)
background block is always (2560 x 780) px
page body width is 820px while height is variable
background block should be behind page body
background block and page body should both be centered
background block should not move relatively to page body when resizing the window (even by 1 pixel !)
no horizontal scroll bar should appear for background block
background block position isn't fixed
Constraints
no JS
CSS2 preferred
What I tried
Page body CSS:
#pageBody {
width: 820px;
margin: 0 auto;
}
Background block CSS:
1. A full-page div which displays a CSS centered background
<div id="backgroundBlock"></div>
<div id="pageBody">
</div>
#backgroundBlock {
background: no-repeat center 0 url(bg.png);
width: 100%;
height: 100%;
position: absolute;
}
But when the window's size is odd:
the CSS background is shifted by 1 pixel on the left
background image appears blurry on Internet Explorer
2. A repositioned child div
make background block a child of page body (which is centered)
make background block positioned absolute (to put it behind page body)
use negative margins to reposition the background block
make background block overflow: hidden to prevent the scroll bar from appear for that div
<div id="pageBody">
<div id="backgroundBlock"></div>
</div>
#backgroundBlock {
background: no-repeat url(bg.png);
width: 2560px;
height: 780px;
position: absolute;
margin: 0 0 0 -870px;
overflow: hidden;
}
But problem: the scroll bar appears for the background block...
Here are a few ideas I could think of, with their issues. However, I could not reproduce the "blurry in IE" issue, so I don't know which solution have it or not.
I did put "Extra markup" as an issue for solutions including a div (#backgroundBlock) only used to display the background image, as it is not semantic.
Solution 1 (jsfiddle)
Description : Your first solution
Issues :
Extra markup
On Chrome, depending on the page size, pixels can be aligned differently. You can see it on jsfiddle near the right border :
Solution 2 (jsfiddle)
Description : Multiple-backgrounds on body. #backgroundBlock div not needed.
body {
background: no-repeat center top url(bg.png), url(bodybg.png);
}
Issues :
Not compatible with old browsers (IE8, FF3.5, ... ; source)
On Chrome, same alignment problem as in solution 1
Solution 3 (jsfiddle)
Description : Use of translate. No more pixel alignment errors.
#backgroundBlock
{
background: url(bg.png);
width: 2560px;
height: 780px;
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, 0);
}
Issues :
Extra markup
You have to use overflow-x: hidden on body to avoid horizontal scrollbar
Not compatible with old browsers (IE8, FF3, ... ; source). You should also use prefixes for compatibility (-webkit-, -moz-, ...). I did not add them to keep the example simple
Solution 4 (jsfiddle)
Description : Use of translate and ::before. Alternative version of solution 3. Pseudo-elements compatibility are not an issue here since every browser supporting 2D-tranforms supports ::before (source).
#backgroundBlock
{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
#backgroundBlock:before
{
content: '';
background: url(bg.png);
width: 2560px;
height: 780px;
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, 0);
}
Issues :
Extra markup
Not compatible with old browsers (IE8, FF3, ... ; source). You should also use prefixes for compatibility (-webkit-, -moz-, ...). I did not add them to keep the example simple
There are other possibilities but I think most of them would have one of the above issues.
For example, you could set the #pageBody width to 2560px, set the background on it, add padding to have a content size of 820px and translate it in order to have it centered on the page (and prevent horizontal scrollbars using overflow-x on body). This would be possible because the background image and page body both have fixed width.
Related
I want to display some random design images on my sites background as background-image, problem now is that every time I place such an image it somehow interacts with nearby boxes etc.
I just want my design images (small icons etc) to be part of the background without getting in touch with other non-design elements like text, boxes etc.
Something like that I guess:
body {
min-height: 100vh;
position: relative;
height: auto;
width: auto;
background-image: url("/static/pattern.jpg");
background-repeat: repeat;
z-index: -10;
} -> "The actual background of the site"
.design_element_01 {
position: relative;
z-index: -1;
background-image: url("/static/xyz.png");
max-width: 100px;
} -> "The design element that should get placed onto the body background from above"
Try:
.design_element_01 {
position: absolute
/*...*/
}
In addition, you might need to change max-width to width, since a background doesn't provide width to the element.
Centering the Background
There are a few different approaches to centering the background. I'll outline one here; if it doesn't work for you, I can describe others.
Essentially, the idea is to make the .design_element_01 element itself take up the entire page. Then, background-size can be used to constrain the size of the background, and background-position can be used to center it. A basic example would be:
.design_element_01 {
position: absolute;
top: 0;
left: 0;
background: url("/static/xyz.png");
width: 100%;
height: 100%;
/* I'm using 100px here since you used max-width: 100px, but you can use whatever you want. */
background-size: 100px;
background-position: center;
background-repeat: no-repeat;
z-index: -1;
}
(Do note that I haven't tested this; you may need to tweak it.)
If you test this example, however, you will notice that this centers the background on the screen, but not necessarily the entire page. This may or may not be what you want. If not, you can change the <body> element's position property:
body {
position: relative;
}
This should cause the .design_element_01 element to be positioned relative to the <body> element.
I also created a JSFiddle example to demonstrate the solution: https://jsfiddle.net/mouqewzv/.
Finally, if you don't want your element completely centered, but just offset from the center, you could tweak the left and top properties of design_element_01 to position the background initially at the center, but then offset it.
Try setting your design_element_01 position to absolute NOT relative
and then try to place it however you want using
left:
right:
top:
bottom:
z-index:
Hope this works!
For whatever reason I am really beating myself up with this... No doubt because of the lack of support for a real "proper" way of vertically centering anything.
The Goal:
Is to have a set of four images, each inside their own responsive columns. Each image has a white overlay, that when hovered reveals more of the image, as well as a title for each of the 4 images that is horizontally and vertically centered inside the image.
I could easily achieve this if I set specific width/heights and stuck the image inside CSS rather than the HTML. For SEO reasons I want the image to be present in the HTML.
Additionally because of the responsive nature, the images must scale to 100% of the width of the column they reside in. Consequently, because the width scales, the height scales as well.
So the first issue is getting the "caption" as I am calling it in my classes, to appear over the top of the image. Easily done with a simple position: absolute; as well as top: 0; and left: 0; on the caption and position: relative; on the container.
The big problem and second issue, is vertically centering the "Gallery 1" text over the top of the image. I have to use the position: absolute; bit as I mentioned above just to get the text over-top of the image. From there I can't manage to get a display: table; solution to work, nor a -50% margin solution to work.
Here is a JS Fiddle
My HTML:
<div class="container">
<img src="http://lorempixel.com/output/city-q-c-640-480-8.jpg" />
<div class="caption">
Gallery 1
</div>
</div>
Any ideas on how to achieve this? I would like to stay at least IE8 supported, and I am using selectivizr already, so pseudo-classes don't bother me.
First, I wasn't sure about what you mean exactly. But as you mentioned:
The issue is centering the text Gallery 1 vertically over the top of the image. Centering it horizontally is easy with a simple text-align but centering it vertically is what is eluding me.
Here is my attempt to align the text vertically over the image. Actually the concept comes from this approach of a similar topic on SO:
.container { position: relative; }
.container img {
vertical-align: bottom; /* Remove the gap at the bottom of inline image */
max-width: 100%;
}
.caption {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
font: 0/0 a; /* Remove the gap between inline(-block) elements */
}
.caption:before {
content: ' ';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.caption a {
font: 16px/1 Arial, sans-serif; /* Reset the font property */
display: inline-block;
vertical-align: middle;
text-align:center;
background: rgba(255, 255, 255, 0.75);
width: 100%;
padding: 1% 0; /* Added a relative padding for the demo */
}
WORKING DEMO.
This relies on CSS2.1 and it will definitely work on IE8+ (excluding rgba()).
If I understand your issue correctly, this may work for you:
Working Demo
If you need the image to scale when hovered over, then simply adding a :hover on the container and changing it's width should work.
CSS:
.container {
// existing styles
-webkit-transition: all .2s; // needs prefixes for other browsers.
}
.container:hover {
width: 500px;
}
The only issue is that transition has no support for IE9 or earlier. So you'd need to go a JS route if that is an issue.
I have created a <div> fixed, set the following styles on it:
#mydiv {
position: fixed;
left: -150px;
width: 150px;
top: 0;
bottom: 0;
border: 1px solid #f00;
}
This produces a <div> that is offscreen, and presumably the same height as the window.
Then I apply the following styles to the <body>:
body {
-webkit-transform: translate(150px, 0);
}
To my knowledge, this should move the body 150px to the right, thereby moving #mydiv into view. This works, but now #mydiv is the height of the body, not the height of the window.
Here's a JSFiddle example
Is this a Webkit bug? Or is this something I'm doing wrong?
EDIT:
This appears to happen on Firefox as well.
The solution to this problem, while perhaps not immediately intuitive, is pretty straightforward.
html, body {
height: 100%;
}
Normally position: fixed elements are aligned relative to the window (the parent of the html element). When css transforms are applied, however, position: fixed elements are aligned relative to the closest parent with a css transform applied.
The alternate approach Webkit and other browsers could have taken, would be to still align position: fixed elements to the window. But the problem with this would be the position: fixed div would not move at all when the body was transformed, and so the div would still be positioned offscreen.
I have problem with margin: auto - vertical centering
#something {
width: 97%;
height: 300px;
border: 1px solid red;
position: absolute;
top: 0;
bottom: 0;
margin: auto;
}
This work in every modern browser - when the page (viewport) is higher then 300px, its centered vertically, but, when the page(viewport) is lower then 300px stopped it works everywhere except in firefox... In firefox run it good (maybe it is bad functionalitiy, but its logical functionality) in other browsers the top of centered element disappers in the top of viewport.
http://jsfiddle.net/LhHed/2/ Here is god example - when you resize result window, in firefox work it well, in others browsers not. Is posible tu fix it? Or its bad functionality of firefox?
EDIT: live example http://dev8.newlogic.cz
From what I gather, you're wanting the top of the divider to display at the top of the page. This currently isn't happening because you have the position set to top:0; bottom:0;, the top property is conflicted by the bottom property, ultimately positions the divider to the bottom of the page. Simply removing the bottom property prevents the top of the element appearing outside of the viewport:
#something {
width: 97%;
height: 300px;
border: 1px solid red;
position: absolute;
top: 0;
margin: auto;
}
JSFiddle.
I removed the problem in browsers, when i use position: relative to the body element. Now its working in firefox and in other browser too. Live example on http://dev8.newlogic.cz
i want a background image that is larger than the content, which will remain centered with the content, but will not affect the layout (meaning no scrollbars to accomodate the background image). the content must be centered using margin: auto; so that the left side will remain flush with the left side of the viewpane, when the viewpane becomes smaller than the content.
I have seen this question asked several times, and have tried quite a few solutions, but none of the accepted answers have actually worked.
Edit to Clarify
This question is still a bit murkey, so I will attempt to clarify with some images showing what I need. In these images, green is the background image, red is the main content, and blue is the browser's viewpane.
A: When the viewpane is smaller than both the background image and the main content, the left side of the content remains flush with the left side of the viewpane, the background image remains centered to the main content, the viewpanes scrollbars will only scroll out to the right edge of the main content (and not to the right edge of the background).
B: When the viewpane is larger than both the background image and content, both remain centered to the viewpane.
C: When the viewpane is the same size as the main content, the background image should remain centered to the main content, no scrollbars should be present.
Updated Answer: I still have spent way too much time on this :-), especially when it ended up so simple. It allows for a background to be sized based on the height of the container, which seems to be different than yunzen's solution. Now does use margin: 0 auto;. Still grows with container height.
View the new answer.
You can view the original, more complex answer which does not use auto margin.
HTML:
<div id="Bkg">
<div id="Content">Content goes here. </div>
</div>
CSS:
#Bkg {
width: 100%;
min-width: 300px; /* equals width of content */
background:url('http://dummyimage.com/400x20/ffff00/000000&text=Center') repeat-y top center;
padding-bottom: 50px;
}
#Content {
width: 300px;
margin: 0 auto;
}
I guess this is what you want
HTML
<div id="content">
content<br/><br /><br/>
content<br/>
</div>
<div id="background"><div></div></div>
CSS
html, body {
height: 100%;
}
#background {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
/* this is the height of the bg image */
min-height: 600px;
z-index: -1;
}
#background > div {
margin: 0 auto;
background: url("http://lorempixel.com/800/600/sports/2") no-repeat 50% top gray;
width: 100%;
height: 100%;
/* this is the height of the content */
min-width: 500px;
/* this is the width of the bg image */
max-width: 800px;
/* this is the height of the bg image */
max-height: 600px;
z-index: -1;
}
#content {
/* these are just some numbers */
width: 500px;
height: 400px;
border: 1px solid gold;
margin: 0 auto;
background: rgba(255,255,255,0.2);
}
Well, if it expands past the browser's window size, it's going to create a scrollbar for the entire window. I wasn't sure exactly what scrollbar you're trying to prevent.
max-width tells it "under no circumstances should this box be bigger than this width." So a box bigger than that will simply expand past the parent's boundaries.
See the jsFiddle.
If I'm understanding the question right, I believe this is what you're wanting.
.main-container
{
height: 1005px;
left: 50%;
margin-left: -560px;
position: relative;
width: 1120px;
}
To hide the scrollbars, you can add
overflow: hidden;
For horizontal only:
overflow-x: hidden;
Try this then:
<div id="wrapper" style="position:relative;margin:auto;width:200px;height:200px;">
<div id="image" style="position:absolute;top:0px;left:-100px;width:400px;height:400px;background-image:url(your_bgimage);background-repeat:no-repeat;background-position:top center;">
<div id="content" style="position:absolute;top:0px;left:100px;width:200px;height:200px;"><p>
<p>/* YOUR CONTENT */</P>
</div></div></div>
For some reason I couldn't get the z-index work, but if you can, you can put your content in the wrapper too, and content is not needed.
Given your original diagram I assumed that the background image was intended to be that - an image, possibly hi-res, rather than a repeated pattern. You may want to play with css3 background-size property which is handy for this specific purpose. It is well supported by modern browsers and regresses reasonably well if you have to support IE8 and under.
body {
background-image:url(/*nice higher res picture*/);
background-size:cover;
background-repeat:no-repeat;
}
http://jsfiddle.net/YyzAX/