Prevent horizontal scrolling outside out main content area - css

So I have a page where the header image can be wider than the width of the content. Say, the content is always 960px wide, but the header image could 1200px wide.
So in order to keep the header image centred I'm using the left: +/-50% trick.
<div class="page">
<header>
<div class="image"><img /></div>
</header>
<article>lots of text...</article>
<div>
div.page {
width: 200px;
background: blue;
margin: 0 auto;
height: 400px;
}
header {
height: 75px;
}
div.image {
position: absolute;
left: 50%;
border: 1px red solid;
}
img {
position: relative;
left: -50%;
height: 50px;
width: 500px;
background: green;
}
article {
background: yellow;
}
So as in this fiddle http://jsfiddle.net/P7F7j/ you can see that horizontal scroll bars display because div.image is off screen, and the same would happen if img is off screen too. Is there any way to remove these elements from the flow so they don't trigger horizontal scrolling?

Make the header min-width: 960px; width: 100%; and set the image as a background-image with style no-repeat center top
That way the header will always be at least 960px and will be filled with your image. Overflowing is handled automatically with background-images.

Related

Scale an image to maximally fit available space and center it

I am building a single page application. In one of the views I want to show an image which must take as much available space as possible:
most important: it must keep the aspect ratio
it must not be cropped
it must be stretched horizontally and/or vertically (without changing aspect ratio) to cover the maximum possible space
the size of the image and viewport are not known
it must be centered
no js must be used
the element must be an img element and no background must be used - I already have a background (in the container)
For example, let's say that the image is 100px x 100px, and that we have a container of 500px x 300px. The image would then be stretched to 300px x 300px, and be horizontally centered so that 100px are left as padding on both sides.
Is this possible?
Here is my non-finished code of what I am trying to accomplish.
.container1 {
width: 500px;
height: 300px;
border: 2px;
border-color: red;
border-style: solid;
}
.container2 {
width: 300px;
height: 500px;
border: 2px;
border-color: blue;
border-style: solid
}
.fill-vertical {
border: 2px;
border-style: solid;
border-color: green;
display: block;
max-width: 100%;
}
.fill-horizontal {
width: 100%;
border: 2px;
border-style: solid;
border-color: green;
}
<h1>Container 1, 500px x 300px, not filled</h1>
<div class="container1">
<img src="https://dummyimage.com/100x100/000/fff">
</div>
<h1>Container 1, filled vertically (should be horizontally centered)</h1>
<div class="container1">
<img class="fill-vertical" src="https://dummyimage.com/100x100/000/fff">
</div>
<h1>Container 300px x 500px, not filled</h1>
<div class="container2">
<img class="fillIt" src="https://dummyimage.com/100x100/000/fff">
</div>
<h1>Container 300px x 500px, filled horizontally, should be vertically centered</h1>
<div class="container2">
<img class="fill-horizontal" src="https://dummyimage.com/100x100/000/fff">
</div>
In that code I am forced to use a different class for the image depending on whether I want to stretch vertically or horizontally, but actually I want CSS to do this automatically: just one stretch class must be defined.
In short what I want CSS to do is: stretch width and/or height to fit available space, keeping aspect ratio
#This can be achieved in CSS with a few changes#
The required changes are:
Create a new .centerImage css rule. overflow: hidden; ensures that the image does not spill out of the container. position: relative; is required as the child img will need to be positioned absolutely relative to the container.
Create a new .centerImage img css rule. max-height: 100%; and max-width: 100% ensures the aspect ratio is kept intact. Setting bottom, left, right and top to 0 and margin: auto; centers the image.
Add the centerImage class to the containing divs.
Change .fill-vertical to height: 100%; which will make the img fill the vertical space.
Change .fill-horizontal to width: 100%; which will make the img fill the horizontal space.
.container1 {
border: 2px;
border-color: red;
border-style: solid;
height: 300px;
width: 500px;
}
.container2 {
border: 2px;
border-color: blue;
border-style: solid;
height: 500px;
width: 300px;
}
.fill-vertical {
height: 100%;
}
.fill-horizontal {
width: 100%;
}
.centerImage {
display: block;
overflow: hidden;
position: relative;
text-align: center;
}
.centerImage img {
bottom: 0;
left: 0;
margin: auto;
max-height: 100%;
max-width: 100%;
position: absolute;
right: 0;
top: 0;
}
<h1>Container 1, 500px x 300px, not filled</h1>
<div class="container1 centerImage">
<img src="https://picsum.photos/500/500">
</div>
<h1>Container 1, filled vertically (should be horizontally centered)</h1>
<div class="container1 centerImage">
<img class="fill-vertical" src="https://picsum.photos/500/500">
</div>
<h1>Container 300px x 500px, not filled</h1>
<div class="container2 centerImage">
<img src="https://picsum.photos/500/500">
</div>
<h1>Container 300px x 500px, filled horizontally, should be vertically centered</h1>
<div class="container2 centerImage">
<img class="fill-horizontal" src="https://picsum.photos/500/500">
</div>
http://jsbin.com/bupuwohica/2/
#Further to the above changes, it is possible to achieve this with the CSS property object-fit#
To do this you need to:
Add object-fit: contain; to the image
Set height and width to 100%
The only caveat to this is browser support as while Firefox, Chrome, Safari and Opera have supported this for some time IE and Edge do not and will require either a polyfill or fallback.
.container {
border: 2px solid red;
height: 200px;
overflow: hidden;
resize: both;
width: 300px;
}
img {
object-fit: contain;
height: 100%;
width: 100%;
}
<p>The below div is resizable, drag the bottom right corner to see how the image scales</p>
<div class="container">
<img alt="" src="https://picsum.photos/500/500" />
</div>
https://jsfiddle.net/efyey801/
Here's one way to do it, relying on background-size. This does use img tags, as required, but the visible graphic is loaded as background to take advantage of available css rules.
.container {
background-color: #edc;
position: relative;
margin: 2em;
}
.container img {
display: block;
width: 100%;
height: 100%;
background-image: url(http://www.clipartbest.com/cliparts/yck/eXb/yckeXboMi.png);
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
#c1 {
width: 400px;
height: 100px;
}
#c2 {
width: 400px;
height: 600px;
}
<div id="c1" class="container">
<img src="">
</div>
<div id="c2" class="container">
<img src="">
</div>
Here's some more information on background-size: https://developer.mozilla.org/en-US/docs/Web/CSS/background-size
Yes it's entirely possible. You just need to make sure you have "Bounds" or limits on your possible max size for X or horizontal and Y or vertical limits. Once you know the max dimensions then you can make those constants to compare to. The easiest method i know of is to compare X and Y as Vectors so you can see their change. To get it centered is also easy at this point:
(((horizontalScreenLimit - widthOfImage)/2), ((verticalScreenLimit - heightOfImage)/2)')

Expand div to fill rest of browser window and center content

I'm trying to achieve a particular layout for a website I'm working on, but I'm not sure how to about it. The layout will look like this:
The header has nothing special about it. The footer has position: fixed and bottom: 0px. The main body content needs to be centred vertically within the space from the bottom of the header down to the top of the footer. If the window height is adjusted, the body content should remain centred between these two points. Also note that the website will be responsive, but only from 960px up to about 1600px (so the minimum width it will ever be is 960px).
My only idea on how to achieve this is to have the div containing the body content somehow automatically expand to always be the full height from the bottom of the header down to the bottom of the browser window (and then add some padding at the bottom to account for the footer), then use display: table on this containing div, and use display: table-cell and vertical-align: middle on a child div.
Are there any other (preferably CSS-only) ways I could potentially do this? If not, how can I get the containing div for the body content expand to always be the full height from the bottom of the header down to the bottom of the browser window?
Here is one solution, for a header with a fixed height.
Your HTML needs to have the following pattern:
<div class="header">Header</div>
<div class="main-wrap">
<div class="container">
<div class="content">Content...</div>
</div>
</div>
<div class="footer">Footer</div>
and the CSS:
html, body {
height: 100%;
}
body {
margin: 0;
}
.header {
height: 50px;
background-color: beige;
}
.main-wrap {
position: absolute;
top: 50px;
bottom: 50px;
width: 100%;
background-color: silver;
overflow: auto;
}
.container {
display: table;
height: 100%;
width: 100%;
}
.content {
border: 1px solid blue;
display: table-cell;
height: 100%;
width: 100%;
vertical-align: middle;
}
.footer {
height: 50px;
width: 100%;
background-color: lightblue;
position: fixed;
bottom: 0;
}
See demo at: http://jsfiddle.net/audetwebdesign/aGTKs/
It is possible to adapt this to a header of flexible height.
The .main-wrap container defines the space between the header and footer.
The .container block uses display: table and inherits the height from .main-wrap.
Finally, .content uses display: table-cell, which allows you to use vertical-align: middle (default value) to center the content vertically.
You need to set the height of body and htmlto be 100% to capture the height of the view port.
You can hack it by doing {position: absolute; bottom: 0} !

Site background image centered and fixed?

I'm working on a site that has a fixed width div that is centered and I wanted to have two designs on either side of the div which I was able to get using two divs. The issue is the way I did it, those images add to the site width, causing a horizontal scroll bar to appear if the window is too small. Even though the whole content div fits with in the screen.
CSS
.container {
margin: 0 auto;
width: 500px;
}
.span {
margin-right: 0;
width: 500px;
}
.logo {
margin-top: 25px;
}
.logo-img {
height: 60px;
left: -21px;
position: relative;
}
.swirls {
height: 0px;
}
.left-swirls {
position: relative;
top: -50px;
right: 100px;
width: 188px;
z-index: -1;
}
.right-swirls {
position: relative;
top: -50px;
left: 215px;
width: 200px;
z-index: -1;
}
.nav {
background-color: #0ff;
}
.content {
background-color: #00f;
height: 200px;
}
HTML
<div class="container">
<div class="span logo">
<img src="http://imageshack.us/a/img839/2507/logongv.png" class="logo-img"/>
</div>
<div class="span swirls">
<img src="http://imageshack.us/a/img831/3254/leftswirls.png" class="left-swirls" />
<img src="http://imageshack.us/a/img600/7424/rightswirls.png" class="right-swirls" />
</div>
<div class="span last nav">
Nav Bar
</div>
<div class="span content">
Body content
</div>
</div>
An example of the issue can be viewed here: http://jsfiddle.net/e4j6b/8/
I'm trying to get the background image(s) centered relative to the div instead of the sides of the browser.
Is there a way to center a background image just like a div with margin: 0 auto?
If you want .left-swirls and .right-swirls to not add to the width of the document, then they should be background images. (For modern browsers, multiple background images work fine.)
Example: http://jsfiddle.net/MbGSP/1/
body {
background: url(http://imageshack.us/a/img831/3254/leftswirls.png) center center no-repeat,
url(http://imageshack.us/a/img600/7424/rightswirls.png) center center no-repeat;
}
You can center background images, both horizontally and vertically, with center center for the positions.

position: absolute, div under div

I've 3 divs, each of them has position: absolute.
First is header, and its working.
Header has constant height, and second div "content" also works.
Third div is "footer".
"Content" has changeable height and when "content" is higher than web-browser window the "footer" is ON "content". I want to "footer" under "content" irrespective of content height.
My header is 300px height, content has margin-top: 300px. I can't use the same for the footer, because content hasn't got constant height.
I don't want to set one div with position: absolute, and these 3 divs place inside this one.
div#header{
width: 960px;
height: 200px;
left: 50%;
margin-left: -480px;
position: absolute;
}
div#content{
width: 960px;
border: 1px solid black;
left: 50%;
margin-left: -480px;
position: absolute;
margin-top: 200px;
}
div#footer{
width: 960px;
height: 30px;
left: 50%;
margin-left: -480px;
position: absolute;
bottom: 10px; /*with this i've div fixed to the bottom of web-browsers' window */
clear: both;
}
You're over positioning.
You do not need to position everything absolutely unless there's something you aren't sharing.
JSBin Example
If you are willing to use position : relative which is a tad better than position : absolute in cases like this, http://jsfiddle.net/vFTXg/1/ - Try editing the value of your content's height here and your footer will be automatically adjusted.
CSS
.header {
position : relative;
width : 100%;
height : 90px;
background-color : #000;
}
.content{
position:relative;
width : 100%;
min-height : 200px;
background-color : #f00;
}
.footer{
position:relative;
width : 100%;
height : 50px;
background-color : #0f0;
}
HTML
<div class='header'></div>
<div class='content'></div>
<div class='footer'></div>
I would recommend using CSS floats
Do something like this:
<div id="wrapper">
<div id="header">...</div>
<div id="content">...</div>
<div id="footer">...</div>
<div class="clear"></div>
</div>
Set the site-width on the wrapper and let the other divs have the same width.
Use float:left on header, content and footer
Set clear:both on the clear-div.
Now you can set the height on the elements you want to have a fixed hight - and you don't have to bother with absolute positioning.. If you insist on using positioning, you could just position the wrapper.
In the future browser can calculate. For your example this could be nice to calculate the min-height for the content to set the foorter to the bottom if content height is low and to set the footer after the content if it has a heigh value. E.g.:
HTML:
<div id="header" class="content">header</div>
<div id="content" class="content">content</div>
<div id="footer" class="content">footer</div>
CSS:
html, body {
height: 100%;
}
.content {
position: relative;
width: 960px;
}
#header {
height: 200px;
}
#content {
border: 1px solid black;
min-height: -moz-calc(100% - 302px);
min-height: -webkit-calc(100% - 302px);
min-height: calc(100% - 302px);
}
#footer {
height: 100px;
}
Unfortunately only firefox and IE9 and higher support calc at the moment, so this is more theoretically. If you want to test it, see this jsfiddle.
If you want to do this with all current browser you need to use javascript.
If you want something to be of constant width and centered try this
#footer,
#header,
#footer {
width: 960px;
margin: 0 auto;
}
and forget about
left: 50%;
margin-left: -480px;
position: absolute;

CSS box stretch to occupy all available room

So I'm trying to create this layout.
Here is a picture of the 3 "boxes" that constitute the page: https://dl.dropbox.com/u/9699560/layout.jpg
And here is my attempt: https://dl.dropbox.com/u/9699560/map.html
The red box is a Google Map, so if its height isn't specified, it shrinks to zero. What I am trying to do is the following:
The green box is fixed width, fixed height. The blue box should occupy 20% of the vertical height of the page, with a maximum height of 100px. The red box should occupy all of the remaining vertical space.
If anyone can figure that out, I'd like to go a little farther, such that when the browser window is expanded vertically and the blue box's top reaches the level of the green box's bottom, it expands left to occupy 100% of the page width.
I've tried floats, absolute, and relative positioning and I cannot get this to work with pure CSS. If I have to, I will use JavaScript, but I would like to avoid that unless it's the only option.
Thanks!
Here's an attempt (remove comments if you use it):
html, body {
margin: 0;
padding: 0;
height: 100%;
}
#nav {
position: relative;
width: 200px;
height: 400px;
background-color: green;
}
#map {
position: absolute;
top: 0;
left: 200px;
right: 0;
height: 80%; // If #footer is 200px, should occupy all available space
background-color: red;
}
#footer {
position: absolute;
left: 200px; // Should "become" 0 when window height pulls it past #nav
right: 0;
bottom: 0;
height: 20%;
max-height: 100px;
background-color: blue;
}
and the HTML
<html>
<head></head>
<body>
<div id="nav"></div>
<div id="map"></div>
<div id="footer"></div>
</body>
</html>
In my opinion, you will need JavaScript to implement this.
My starting point would probably be from this markup, maybe implement the min/max height behaviors in an event handler that fires on resize :
CSS
html, body { margin: 0; padding: 0; }
#nav { background-color:green; width: 200px; height: 400px; float:left; }
#map { background-color:red; height: 80%; margin-left: 200px; }
#footer { background-color: blue; height:20%; }
HTML
<div id="nav">nav content</div>
<div id="map">map content</div>
<div id="footer">footer content</div>

Resources