Scrollbar visible even when is not necessary - - html

I have an error using overflow:auto.
The error: http://cl.ly/image/0K1W3t151T0S
The code I used http://codepen.io/sebazelonka/pen/pDGin
Even when the height of the content has the same height than container, the scrollbar is visible. I tried different options, but the error persist.
I tried it in different browsers, including FF, Chrome, Safari and Opera, and always have the same error.
HTML
<div class="image-viewport portrait" style="width: 100%; height: 400px;">
<div class="image-wrapper" style="width: 100%; height: 400px;">
<img src="http://www.hdwallpapersview.com/wp-content/uploads/2013/05/landscape_7.jpg">
</div>
</div>
CSS
body {
background: #999;
}
.image-viewport {
overflow: auto;
}
.image-wrapper {
background: #333;
text-align: center;
}
.image-viewport.portrait img {
height: 100%;
}

Here are 2 different solutions:
Add vertical-align:top to the img element. (default is vertical-align:baseline)
Change the img to a block level element.
Updated Codepen example using vertical-align:top
.image-viewport.portrait img {
height: 100%;
vertical-align:top;
}
Updated Codepen example using display:block
Note: For horizontal centering, use margin:0 auto, as text-align:center will no longer work, as the element is not an inline element anymore.
.image-viewport.portrait img {
height: 100%;
display:block;
margin:0 auto;
}
Also, don't be confused with the scrollbar added on the body if the window is too small. The scrollbar on the img wrapper has been removed.

Just change your .image-viewport class to this:
.image-viewport {
overflow: hidden;
}

Related

How to stop img from overflowing?

My problem is that I have an image that I would like to use as the logo for the website. The header and div that it is in are properly sized (i checked by inspecting it on chrome) , but the img is overflowing. How do i scale it down?
(I will use a placeholder image for the code)
Here is the code:
<body>
<header class="mainheader">
<a href="main.html" class="navelement">
<div class="imgcontainer">
<img src="https://lh3.googleusercontent.com/-Ajc8gSO3SRw/VtZj0tsyXhI/AAAAAAAAAHs/tlsdyufJ1J4/w868-h560/2.png"/>
</div>
</a>
</header>
</body>
Here is the accompanying css, I'm confused why the max-height isn't working.
* {
box-sizing: border-box;
}
body{
margin: 0;
}
header{
height:10vh;
width: 100%;
float left:
margin: 0;
background-color:grey;
font-family: 'Teko', sans-serif;
display: inline-block;
}
header .navElement {
vertical-align: middle;
float:left;
width: 17%;
}
.imgcontainer{
float:left;
max-height: 100%;
}
.imgcontainer img{
float:left;
max-height:100%;
}
I realize some things are unnecessary but its because i've tried so much to fix it that i don't know what works. Thanks for any helpful replies.
To prevent overflowing of content, you can simply use the corresponding css-property: overflow: hidden. If you do so, the content which is overflowing, will simply get cut off. In your example, this wouldn't be the right approach.
Instead of using max-height you may use height. By doing so, you'll assign an absolute value for your elements. Since your .imagecontainer only has a max-height property, try replacing it with height, as shown here.
.imgcontainer {
float: left;
height: 100%;
}

div does not get centered using margin: auto in IE9

I am trying to get a centered in the space that is left empty by a sidebar. This is how I'd like it to look like:
I actually managed to make this work OK for most browsers using margin: auto for the div in question, while setting overflow: hidden:
Fiddle here
CSS
#header {
height: 50px;
background: #224444;
color: #fff;
}
#container div {
padding: 1em;
}
#content {
max-width: 400px;
margin: auto;
background: #ddd;
height: 300px;
overflow: hidden;
}
#sidebar {
float: right;
width: 200px;
background: #aaa;
height: 300px;
}
HTML
<div id="container">
<div id="header">
PAGE HEADER
</div>
<div id="sidebar">
Sidebar
</div>
<div id="content">
Centered Content
(Works everywhere but on IE9)
</div>
</div>
However, it does not work with IE9. It is strange as IE8 works OK!
I am running out of ideas, so I thought that maybe someone knows what is going on? The trick seems to work perfectly everywhere else.
NOTE: Please note that the content div should be flexible as it is in the demo. As the available space decreases, it should change size and squeeze in.
Isolate the centering from the floating
This affects IE9/10.
It works fine if the floated element is removed, or if width is used instead of max-width. The presence of floated content, combined with the use of margin:auto and max-width instead of width, appears to be confusing IE9+.
To fix this, put the centered content in a wrapper div, so that the centering of the content can be separated from the floating of the sidebar. In other words, too much is happening layout-wise in a single div, more than IE9+ can handle. So split up the #content div into two separate divs.
#header {
height: 50px;
padding: 1em;
background: #224444;
color: #fff;
}
#content-wrapper {
overflow: hidden;
}
#content {
max-width: 400px;
margin: auto;
padding: 1em;
background: #ddd;
height: 300px;
}
#sidebar {
float: right;
width: 200px;
padding: 1em;
background: #aaa;
height: 300px;
}
<div id="container">
<div id="header">
PAGE HEADER
</div>
<div id="sidebar">
Sidebar
</div>
<div id="content-wrapper">
<div id="content">
Centered Content
</div>
</div>
</div>
This tested fine in IE7/8/9/10. On a side note, because a wrapper div was added, the padding: 1em; now has to be added to each element individually.
IE is notorious for not working without proper doctypes.
Try adding the HTML5 one
<!DOCTYPE html>
Floats are a tricky business. Strictly speaking, they're only supposed to affect the inline content that flows around them, so margins acts like the floats aren't even there.
Try this instead:
#container {text-align:center}
#content {display:inline-block;text-align:left}
This should make the content box act like an inline element, and therefore appear centered in the space.
As far as I remeber I've always problems with margin:0 auto because I didn't specify width property.
So everytime you want use margin:auto you propably should write this:
#content {
max-width: 400px;
margin: auto;
background: #ddd;
height: 300px;
overflow: hidden;
width:500px;
}
or in percentage:
#content {
max-width: 400px;
margin: auto;
background: #ddd;
height: 300px;
overflow: hidden;
width:30%;
}
EDIT
If you want to create flexible layout please take a look to bootstrap and fluid grids.

No padding when using overflow: auto

I can’t get padding-bottom to work when I use overflow-y: auto on a box. I use Firefox.
#container {
padding: 3em;
overflow-x: hidden;
overflow-y: auto;
width: 300px;
height: 300px;
background: red;
}
#some_info {
height: 900px;
background: #000;
}
<div id="container">
<div id="some_info"></div>
</div>
See the JSFiddle.
One more solution without extra DIVs.
#container:after {
content: "";
display: block;
height: 50px;
width: 100%;
}
Working in FF, Chrome, IE8-10.
I'm late to the party, but I thought it was worth adding a different solution that addresses some of the concerns raised above.
I came here because of exactly the kind of situation that #Philip raised in response to Alexandre Lavoie's solution: I have dynamically generated content inside the container, so I can't just apply styling to a specific div name like #some_info.
Happily, there's a simple solution for browsers that support CSS3: instead of applying bottom padding to the container, apply a bottom margin to the last child element inside the container.
#container > :last-child {
margin-bottom: 3em;
}
As long as the last child element in the container div is a block-level element, this should do the trick.
DEMO: http://jsfiddle.net/rwgZu/240/
P.S. If Firefox's failure to scroll to the bottom of the padding is indeed a bug (as suggested by #Kyle), it still hasn't been fixed as of Firefox 47.0. Frustrating! Internet Explorer 11.0.9600.17843 exhibits the same behavior. (Google Chrome, in contrast, shows the bottom padding as expected.)
The solutions above were not working for my needs, and I think I stumbled on a simple solution.
If your container and overflowing content share the same background color, you can add a top and bottom border with the color matching the background color. To create equal padding all around, set the border width equal to the left and right padding of the container.
Link to modified version of OP's fiddle: http://jsfiddle.net/dennisoneil/rwgZu/508/
A simple example below.
Note: Stack Overflow puts the snippet results into an overflow scroll, which makes it a little harder to see what's going on. The fiddle may be your best preview option.
#container {
background: #ccc;
overflow-y: scroll;
height: 190px;
padding: 0 20px;
border-top: 20px solid #ccc;
border-bottom: 20px solid #ccc;
}
#overflowing {
background: #ccc;
}
<div id="container">
<div id="overflowing">
This is content<br/>
This is content<br/>
This is content<br/>
This is content<br/>
This is content<br/>
This is content<br/>
This is content<br/>
This is content<br/>
This is content<br/>
This is content<br/>
This is content<br/>
This is content<br/>
This is content<br/>
This is content<br/>
This is content<br/>
</div>
</div>
Here is a possible approach that is working perfectly :
#container {
overflow-x: hidden;
overflow-y: auto;
width: 300px;
height: 300px;
}
#some_info {
height: 900px;
background: #000;
border: 3em solid red;
}
Style the parent div normally and make the inner div do what you want it to do.
Remove overflow-x and overflow on #container, change height to 100% and add overflow-y:scroll; on #some_info
#container {
padding: 3em;
width: 300px;
height: 300px;
background: red;
}
#some_info {
height: 100%;
background: #000;
overflow-y:scroll;
width:100%;
}
Working Demo: http://jsfiddle.net/9yuohxuh/
For those who are looking for a simple solution and can change the DOM, put the overflow on the outer element and the padding on the inner element.
.scroll {
overflow-x: hidden;
overflow-y: auto;
}
.scroll__inner {
padding: 3em;
}
In the example from the original question, it would look like this:
#container {
overflow-x: hidden;
overflow-y: auto;
width: 300px;
height: 300px;
background: red;
}
#some_info {
height: 900px;
background: #000;
padding: 3em;
box-sizing: border-box; /* only needed if wanting padding to not be added to height */
}
Note the use of box-sizing: border-box here, which is only needed as the OP has a hardcoded height (generally bad practice but could be needed in edge cases), so adding this border-box enables the 3em padding to not increase the height, but pad inside the 900px.
A final note, I'd advise avoiding ID's for styling, mostly due to their extremely high specificity, see this post for more info on that.
Demo
Hi now used to this css
#container {
padding: 3em;
overflow-x: hidden;
overflow-y: auto;
width: 300px;
height: 300px;
background: red;
padding-bottom:0; // add this line in your css
}
#some_info {
height: 900px;
background: #000;
margin-bottom:3em; // add this line in your css
}
Demo
It's not only with bottom padding. Right padding/border/spacing is also ignored (you can't see it in your example because it has no content, and the width is not scrolling)
All the answers above fail in chrome 43, generating up to 3 scrollbars! or if the content overflows #some_info.
Example: http://jsfiddle.net/LwujL3ad/
If it worked for you, it's probably because the content was not as wide as the scrolling element, or fixed sized.
The right solution is:
Set #some info to display:table, and add padding or border to it, not to the scrolling container.
#container {
overflow: scroll;
width: 300px;
height: 300px;
background: red;
padding-bottom:0;
}
#some_info {
display:table;
border: solid 3em red;
height: 900px;
background: #000;
margin-bottom:3em;
color: white;
}
DEMO: http://jsfiddle.net/juh7802x/
The only element that doesn't fail, and respects ANY border and padding you add in there as separator is a TABLE.
I tried, and no matter if it's the next direct child or it's nested many items deep, any non-content styling will NOT expand to wrap the content, and will stay 100% width of the parent. Which is nonsense, because having content BIGGER than the parent is EXACTLY the scenario in which a scrolling div is required!
For a dynamic solution (both the container and the content) set the container of the elements inside the scrolling container to display:table.
Based on isHristov's answer:
#container {
padding: 3em 3em 0 3em; /* padding-bottom: 0 */
overflow-x: hidden;
overflow-y: auto;
width: 300px;
height: 300px;
background: red;
}
#container:after {
content: "";
display: block;
height: 0;
width: 100%;
margin-bottom: 3em; /* length you wanted on padding-bottom */
}
However, his solution adds extra space in browsers that handle this situation properly.
Dan Robinson's answer is great too unless you have multiple elements, in #container, that are dynamically shown/hidden. In that case :last-child might target a hidden element and have no effect.
You just need to add box-sizing: border-box to the same element where you applied the overflow rule.
I think #-moz-document url-prefix() is what you need.
#container {
padding: 3em;
overflow-x: hidden;
overflow-y: auto;
width: 300px;
height: 300px;
background: red;
}
#some_info {
height: 900px;
background: #000;
}
#-moz-document url-prefix() {
#container > :last-child {
margin-bottom: 3em;
}
}
<div id="container">
<div id="some_info"></div>
</div>
The top answers did not work in FireFox 89. The only sensible solution I could think of is to use a div containing only a non-breaking space and with a fixed height set.
HTML
<div className="spacer"> </div>
CSS
.spacer {
height: 30px;
}
This works as it does not utilize margin or padding.
I have just faced this issue, it persists even in Firefox 87, version being released in 2021.
But it is finally fixed very recently. After update to Firefox 93 bottom padding with scroll works normally.

Bottom margin of last child gets hidden when overflow applies

I have a container div which has children anchored to the bottom. The problem is that when the div's overflow scrollbar appears, the bottom margin of the last child gets hidden.
Please see http://jsfiddle.net/TxEAP/3/. At first, there's a correct margin underneath the 1 div. Clicking "append one" so that the scrollbar eventually appears makes the last div not have a bottom margin anymore. Opening DevTools shows that the margin of that last child is there, but it is outside of the container's viewport, even when scrolling completely to the bottom.
How can this be solved? It would suffice to get this working in Google Chrome.
HTML:
<div class="main">
<div class="container">
<div class="item">1</div>
<!-- several of these .item divs -->
</div>
</div>
CSS:
.main {
height: 200px;
overflow-y: scroll;
position: relative;
border: 1px solid black;
}
.container {
width: 100%;
max-height: 100%;
position: absolute;
bottom: 0;
}
.item {
padding: 20px;
margin: 15px;
border: 1px solid black;
}​
Here's my final solution using flexbox. It's supported well enough on Chrome despite all -webkit- prefixes. Basically, the idea is to have a dummy element that, in case of no overflow, fills up the space of the container starting from the top (so that the real children are anchored to the bottom); in case of overflow, it is hidden automatically because of height: 0. It does not suffer from the margin issue, and it does not collapse margins.
http://jsfiddle.net/mCYLm/1/
HTML:
<div class="main">
<div class="gap-filler"></div>
<div class="item">foo</div>
<!-- more `div.item`s -->
</div>
CSS:
div.main {
display: -webkit-box;
-webkit-box-orient: vertical;
height: 200px;
overflow-y: scroll;
}
div.main div.gap-filler {
-webkit-box-flex: 1;
height: 0;
}
div.main div.item {
border: 1px solid black;
margin: 20px;
padding: 20px;
}​
Edit: This was a solution without flexbox, but it had selection issues.
A solution that eventually worked was the following: http://jsfiddle.net/TxEAP/7/. This appends hidden "content" which makes Chrome not hide the margin of the last .item div.
.container:after {
content: "";
font-size: 0;
display: block;
height: 1px;
}
Edit: The following only works if display: inline-block is possible.
Finally I found a solution. If all .items have display: inline-block except the first one, then the margin does not get hidden.
http://jsfiddle.net/TxEAP/5/
.item:not(:first-child) {
display: inline-block;
/* attempt at getting `width: auto` like `display: block` has */
width: -webkit-calc(100% - 2 * 15px);
box-sizing: border-box;
}
If you just move the overflow-y: scroll; from .main. to .container class then the margin is preserved. The only drawback is for less than 3 items (for the given container height) you get a small scrollbar placeholder, instead of a full height one.
Removing max-height:100% on the container seems to fix it for my test in Chrome 21.
Moving the properties so that the overflow is on the container, preserves the margin/padding for an element added to the end that results in the scrollbar appearing.
.main {
height: 200px;
border: 1px solid black;
}
.container {
width: 100%;
height: 100%;
overflow-y: scroll;
}

center image in div with overflow hidden

I have an image of 400px and a div that is smaller (the width is not always 300px as in my example). I want to center the image in the div, and if there is an overflow, hide it.
Note: I must keep the position:absolute on the image. I'm working with css-transitions, and if I use position:relative, my image shakes a bit (https://web.archive.org/web/20120528225923/http://ta6.maxplus.be:8888/).
jsfiddle
http://jsfiddle.net/wjw83/1/
You should make the container relative and give it a height as well and you're done.
http://jsfiddle.net/jaap/wjw83/4/
.main {
width: 300px;
margin: 0 auto;
overflow: hidden;
position: relative;
height: 200px;
}
img.absolute {
left: 50%;
margin-left: -200px;
position: absolute;
}
<div class="main">
<img class="absolute" src="http://via.placeholder.com/400x200/A44/EED?text=Hello" alt="" />
</div>
<br />
<img src="http://via.placeholder.com/400x200/A44/EED?text=Hello" alt="" />
If you want to you can also center the image vertically by adding a negative margin and top position: http://jsfiddle.net/jaap/wjw83/5/
None of the above solutions were working out well for me. I needed a dynamic image size to fit in a circular parent container with overflow:hidden
.circle-container {
width:100px;
height:100px;
text-align:center;
border-radius:50%;
overflow:hidden;
}
.circle-img img {
min-width:100px;
max-width:none;
height:100px;
margin:0 -100%;
}
Working example here:
http://codepen.io/simgooder/pen/yNmXer
Most recent solution:
HTML
<div class="parent">
<img src="image.jpg" height="600" width="600"/>
</div>
CSS
.parent {
width: 200px;
height: 200px;
overflow: hidden;
/* Magic */
display: flex;
align-items: center; /* vertical */
justify-content: center; /* horizontal */
}
Found this nice solution by MELISSA PENTA (https://www.localwisdom.com/)
HTML
<div class="wrapper">
<img src="image.jpg" />
</div>
CSS
div.wrapper {
height:200px;
line-height:200px;
overflow:hidden;
text-align:center;
width:200px;
}
div.wrapper img {
margin:-100%;
}
Center any size image in div
Used with rounded wrapper and different sized images.
CSS
.item-image {
border: 5px solid #ccc;
border-radius: 100%;
margin: 0 auto;
height: 200px;
width: 200px;
overflow: hidden;
text-align: center;
}
.item-image img {
height: 200px;
margin: -100%;
max-width: none;
width: auto;
}
Working example here codepen
For me flex-box worked perfect to center the image.
this is my html-code:
<div class="img-wrapper">
<img src="..." >
</div>
and this i used for css:
I wanted the Image same wide as the wrapper-element, but if the height is greater than the height of the wrapper-element it should be "cropped"/not displayed.
.img-wrapper{
width: 100%;
height: 50%;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
img {
height: auto;
width: 100%;
}
working solution with flex-box for posterity:
main points:
overflow hidden for wrapper
image height and width must be specified, cannot be percentage.
use any method you want to center the image.
wrapper {
width: 80;
height: 80;
overflow: hidden;
align-items: center;
justify-content: center;
}
image {
width: min-content;
height: min-content;
}
<html>
<head>
<style type="text/css">
.div-main{
height:200px;
width:200px;
overflow: hidden;
background:url(img.jpg) no-repeat center center
}
</style>
</head>
<body>
<div class="div-main">
</div>
</body>
just make sure how you are using image through css background use backgroud image position like background: url(your image path) no-repeat center center; automatically it wil align center to the screen.
this seems to work on our site, using your ideas and a little math based upon the left edge of wrapper div. It seems redundant to go left 50% then take out 50% extra margin, but it seems to work.
div.ImgWrapper {
width: 160px;
height: 160px
overflow: hidden;
text-align: center;
}
img.CropCenter {
left: 50%;
margin-left: -100%;
position: relative;
width: auto !important;
height: 160px !important;
}
<div class="ImgWrapper">
<img class="CropCenter" src="img.png">
</div>
I have been trying to implement Jaap's answer inside this page of my recent site, with one difference : the .main {height:} was set to auto instead of a fixed px value.
As responsive developer i am looking for a solution to synchronize the image height with the left floating text element, yet only in case my text height becomes greater then my actual image height.
In that case the image should not be rescaled, but cropped and centered as decribed in the original question here above.
Can this be done ?
You can simulate the behaviour by slowly downsizing the browser's width.
This issue is a huge pain in the a.. but I finally got it.
I've seen a lot of complicated solutions. This is so simple now that I see it.
.parent {
width:70px;
height:70px;
}
.child {
height:100%;
width:10000px; /* Or some other impossibly large number */
margin-left: -4965px; /* -1*((child width-parent width)/2) */
}
.child img {
display:block; /* won't work without this */
height:100%;
margin:0 auto;
}
you the have to corp your image from sides to hide it try this
3 Easy and Fast CSS Techniques for Faux Image Cropping | Css ...
one of the demo for the first way on the site above
try demo
i will do some reading on it too