Unnecessary scrollbars appear for inline-block - html

While I was coding a website, I happened to stumble upon something peculiar.
Here's my code:
HTML
<div id='a'><div id='b'></div></div>
CSS
html{height:100%}
body
{
margin: 0;
height: 100%;
background: green;
padding: 0 5%;
}
#a
{
height: 100%;
background: blue;
text-align: center;
}
#b
{
display: inline-block;
height: 100%;
background: red;
width: 50%;
}
And a JSFiddle, just in case: http://jsfiddle.net/ud3y1vh2/
The problem is that an unnecessary vertical scrollbar appears, even though none of the elements supposedly overflow. I'm familiar with the regular two-inline-blocks-next-to-eachother problem that causes whitespace to appear between the elements, but this seems to be a bit tougher nut to crack.
What I've thought of:
Removing any and all whitespace in the HTML
overflow:hidden on #a - Works, but can't be used for my website (user has to be able to scroll the content when needed)
font-size:0 on #a - Works, but can't be used, since my website uses ems for sizing #a and other elements. Not a viable solution for me.
Making #b a block-type element, or lowering it's height - Works, but not viable for my website.
So if you can come up with any ideas on how to remove the scrollbar (or rather, remove the cause of the scrollbar), I'd like to hear them.

The scrollbar can be removed by changing the vertical-align property of the inline-block element to a value such as top. The default vertical-align value is baseline, which is why the element is being aligned to the bottom (resulting in a scrollbar)..
Updated Example
#b {
display: inline-block;
vertical-align: top;
height: 100%;
background: red;
width: 50%;
}

Related

How do I set a center container to stay responsive?

I have three containers (div), the third div has a set width but I need the other two to be responsive. Current html setup:
<div id="page-type">
<div id="type-container">
<div>
<p id="type-title">Events</p>
</div>
</div>
<div class="type-options">
</div>
<div id="type-back">
Back to Explore
</div>
</div>
Current css:
#page-type {
float: left;
width: 100%;
background: #D2D3D5;
height: 60px;
}
#type-container {
float: left;
width: auto;
}
#type-options {
height: 60px;
width: auto;
overflow: hidden;
}
#type-back {
border-left: 1px #BDBEC1 solid;
float: right;
width: 160px;
}
I can get type-container and type-options to be on the same line and responsive but I can't keep type-back on the same line.
visual example:
----- EDIT -----
To clarify more:
type-container adjusts to fit it's content
type-back is a set width
type-option fills in the space between type-container and type-back regardless of content
type-containerand type-options fill up the whole row pushing type-back to the next line. I need type-back to stay to the right of the line while the other two are responsive.
Put a wrapper around your first two columns and then you can use CSS3's calc().
#wrapper {
width: calc(100% - 161px); /* extra px for 1px border */
float: left;
}
Demo here
IE8 Workaround - Use border-box:
#wrapper {
margin-right: -161px;
padding-right: 161px;
width: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
IE8 Demo
In CSS3 you can use calc(X% - 160px) to reduce the width of a percentage based container by a number of pixels.
A quick example could be: http://jsfiddle.net/e3vC4/
There isn't a need to use calc for this, even though its a nice feature to have (+1) — sadly its support is still patchy in places and despite much research it's still difficult to say exactly which browser versions will work as expected (fine if you assume all modern browser users auto-upgrade however).
Depending on what your prerequisites are, you have two other options that I'm aware of:
1. Position absolute the last column
This is a simple solution, however something to be wary of is that certain older mobile devices may treat position absolute in odd ways.
In order to get this to work, all you need to do is place position: relative on your container, and position: absolute; right: 0; top: 0; on your third column... and to keep the centering of your central column correct, add margin-right: 161px.
Pos. Abs. example on JSFiddle
CSS ~ markup is as per your example
#page-type {
display: block;
position: relative; /* added */
width: 100%;
background: #D2D3D5;
height: 60px;
overflow: hidden;
}
#type-container {
display: block;
float: left;
text-align: center;
}
#type-options {
display: block;
height: 100%;
text-align: center;
overflow: hidden;
margin-right: 161px; /* added */
}
#type-back {
display: block;
position: absolute; /* added */
right: 0; /* added */
top: 0; /* added */
border-left: 1px #BDBEC1 solid;
width: 160px;
height: 100%;
}
2. Float right, and/or left, before sibling without hasLayout / shrinkwrap
This works on the basis that a floated element takes up space in the document, and a block element, by default, auto-expands to fill the remaining area that it can — as long as it hasn't been forced to rigidly define its edges with the likes of float, overflow or other hasLayout or shrinkwrap tricks.
This option is only open to you if you can re-arrange your DOM ordering i.e. place #type-back before #type-options. This won't affect the visual order, but it makes a big difference to how the layout is calculated, and is one of the reasons why you were encountering problems with your attempts. You need to have the floated elements in place before leaving the other elements to calculate their dimensions.
Float example on JSFiddle
NOTE: Changing the order of DOM elements can be of benefit, but it can also be a hindrance; it all depends on what the markup is, and who will be viewing it. For example, sometimes having actionable links higher up the DOM can be useful to tabbing and screen-reader users, but the opposite can also be true depending on the context.
MARKUP ~ note the rearranged DOM order
<div id="page-type">
<div id="type-container">
<p id="type-title">Events</p>
</div>
<div id="type-back">
<p>Back to Explore</p>
</div>
<div id="type-options">
<p>Options</p>
</div>
</div>
CSS
#page-type {
display: block;
width: 100%;
background: #D2D3D5;
height: 60px;
overflow: hidden;
}
#type-container {
display: block;
float: left;
text-align: center;
}
#type-options {
display: block;
height: 100%;
text-align: center;
overflow: hidden;
}
#type-back {
float: right;
border-left: 1px #BDBEC1 solid;
width: 160px;
height: 100%;
}
NOTE: It should be stated this version does break on to the next line when "responsed" down to a very minimal size. However, I tend to prefer to design items to disappear when space is tight, and this method lends well to that thinking.
Summary
These are just two other possible options. If you are developing for a progressive client, or yourself, then I personally would stick with the calc method. It's easier to work out what is going on, and far easier for a future developer to change.
However, sometimes often frequently all the blasted time clients want to support the widest range of devices possible (without investing the extra time and money that would be required), and in this instance you are better off with an alternative method (one that isn't going to randomly break on a manager's less than contemporary laptop, running IE 7.5? or 8.33333??? or even Netscape 4.7¿).
Unless of course, you have any leeway to fight for using the more progressive approach, which does seem to be getting easier of late.
I sat down with the designer for more clarification and to discuss alternate solutions. I'm making the third did responsive as well allowing me to use two containers: one holds page-type and type-options set to x% and another holds type-back set to y%. Doing this allows me to keep all elements responsive.

Force divs to be on the same line

I am trying to make a div with text and a div with a button fit side by side. It works fine until you make the screen really narrow. Is there a way to force them to be on the same line and for the first div to shrink to accommodate the min-width of the second?
http://jsfiddle.net/C3877/9/
To see what I mean, resize the window, reducing the width, until the div with the button is forced onto the second line. That is what I'd like to prevent.
Note: I only care if a suggested fix works properly in Chrome.
Instead of floats, you could use display: inline-block. This will keep things all on one line, and respect the min-width as well.
Inline-block fiddle: http://jsfiddle.net/C3877/8/
In addition, since you only care about Chrome, you could look into flexible boxes
A (quick) flex fiddle here: http://jsfiddle.net/C3877/11/
You can use negative margin-left for the floated right element. Note that this solution keeps using float for both the left and right divs, without using float, you have dozens of solutions (as some of other answers pointed out).
#right_div {
...
margin-left:-100%;
}
Note that all the next content should be wrapped in a block element and use clear:both. I also added a sample of such an element with background:green in this DEMO.
Appending this does the trick I suppose:
#media (max-width:515px) {
#left_div { width: 100%; margin-right: -100px }
}
UPDATED
You could use margin and absolute positioning:
CSS
#parent_div {
width: 100%;
height: 10%;
position: relative;
min-width: 40px;
}
#left_div {
width: 80%;
min-width: 100px;
height: 80%;
float: left;
background-color: #000;
color: #FFF;
}
#right_div {
width: 15%;
min-width: 100px;
float: right;
background-color: blue;
position:absolute;
right: 0px;
}
input[type=button] {
font-size: 2rem;
}
SEE DEMO: http://jsfiddle.net/C3877/19/
You will have to play with some of the css to get it just right when you move it on your website. But this is a sure quick fix.

HTML Inline-Block DIVs Not Lining Up

So I am designing a website right now (pretty nooby at HTML and CSS) but I made a design on Photoshop beforehand so that I could go right through the coding and make the website how I wanted. Well I have an issue. I have two DIV elements inside of a bigger container DIV that won't line up side-by-side, despite using inline-block. Here is the css code:
.contentContainer {
display: block;
width: 700px;
height: 250px;
margin: 20px auto;
}
.topContainer {
height: 230px;
padding: 10px;
background-color: white;
}
.topThumbnail {
display: inline-block;
width: 370px;
height: 230px;
}
.topThumbnail img {
width: 370px;
height: 230px;
}
.topInfo {
display: inline-block;
margin-left: 10px;
width: 300px;
height: 230px;
}
.topInfo p {
width: 300px;
height: 230px;
background-color: pink;
}
The contentContainer is the highest DIV holding my topContent and topThumbnail so I thought I'd throw it into the provided code.
And the HTML code:
<div class="topContainer">
<div class="topThumbnail">
<img src="YT.png" />
</div>
<div class="topInfo">
<p>Testing the information area of the top container or something along those lines</p>
</div>
</div>
Can't post pictures to explain the issue.. need 10 reputation.. will make it hard to describe.
In the design the two containers for the Thumbnail and the Info are supposed to be side-by-side and aligned at the top. The thumbnail is supposed to be on the left of the topContainer and the Info is supposed to be to the right of the thumbnail with a margin of 10. For some reason the info is not going to the right-side of the thumbnail but rather going under it. I have ALREADY set the margin to 0 to fix the default margin issues.
display: inline-block is working correctly in your example. What you need to add is vertical-align: top to your .topInfo div, and get rid of the default margin on your .topInfo p tag. Also, you need to make sure that there is enough room for the .topInfo div to sit to the side of the .topThumbnail div, otherwise it will wrap to the next line.
Like this:
http://jsfiddle.net/hsdLT/
A cleaner solution: I would look at ditching the display:inline-block CSS proporties on these elements altogether and just float them to the left. Then clear the floats by assigning clear:both to the .topInfo css property.
It's less code then your route will be and it's more structurally sound. :D.
.topThumbnail,
.topInfo {
float:left;
}
.topInfo {
clear:both;
}
Other people have already answered this with the solution, but I think it is important to understand why inline-block elements behave this way. All inline, table, and in this case, inline-block elements have the vertical-align property. The default value is set to baseline, hence the need to set vertical-align: top;.
See the docs here: https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align.
This other discussion is also helpful: Vertical alignment for two inline-block elements not working as expected

<div> wrapper dynamic height

I have a wrapper that contains all the elements of an html page.
#wrapper {
width: 1000px;
height: auto;
min-height: 100%;
margin: auto;
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#4488ff), to(#4422ff));
[...]
background-attachment: fixed;
-moz-border-radius:20px;
-webkit-border-radius:20px;
border-radius:20px;
}
Here's the HTML code sample
<div id="wrapper">
<div id="uppermenu">
<div id="container">
<div id="logo"> <img src="images/logo.png" height="100%"> </div>
<div id="banner"> <br></div>
</div>
</div>
<div class="sidemenu"> [...] </div>
<div id="guide"> [...] </div>
</div>
I want this wrapper to change its height depending on the content it has to contain, but as I do this is not happening.
If I try to use
overflow: hidden;
the wrapper is shifted down by the uppermenu div (which it should be containing) and using
clear: both;
at the end of the contents doesn't change anything.
I've tried at least 5 different question answered correctly here but none worked well for me.
Last thing: the wrapper set as I wrote (with min-height at 100%) fits perfectly the screen of my browser, but that clearly not what I want it to look!
Any help???
EDIT: here's the CSS of sidemenu class
.sidemenu {
float: left;
margin-left: 20px;
margin-top: 20px;
height: 200px;
width: 150px;
background-color: #4488ff;
-moz-border-radius:10px;
-webkit-border-radius:10px;
border-radius:10px;
z-index: 3;
}
and of the guide id
#guide {
float: left;
margin-top: 20px;
margin-left: 50px;
height: 100%;
width: 760px;
background-color: #4488ff;
-moz-border-radius:10px;
-webkit-border-radius:10px;
border-radius:10px;
z-index: 3;
}
uppermenu and container
#uppermenu {
position: fixed;
top: 0px;
width: 1000px;
height: 100px;
margin: auto;
background: #004465;
z-index: 5;
}
#container {
width: 1000px;
min-height: 100%;
margin: auto;
}
Solution one: clear: both
Adding a block element with the style clear:both; onto it will clear the floats past that point and stop the parent of that element from collapsing. http://jsfiddle.net/TVD2X/1/
Pros: Allows you to clear an element and elements you add below will not be effected by the floated elements above and valid css.
Cons: Requires the another tag to clear the floats, bloating markup.
Note: To fall back to IE6 and for it to work on abstinent parents (i.e. the input element) you are not able to use :after.
Solution two: display: table
Adding display:table; to the parent to make it shrug off the floats and display with the correct height. http://jsfiddle.net/h9GAZ/1/
Pros: No extra markup and is a lot neater. Works in IE6+
Cons: Requires invalid css to make sure everything plays nice in IE6 and 7.
Note: The IE6 and 7 width auto is used to prevent the width being 100%+padding, which is not the case in newer browsers.
A note on the other "solutions"
These fixes work back to the lowest supported browser, over 1% usage globally (IE6), which means using :after does not cut it.
Overflow hidden does show the content but does not prevent the element from collapsing and so does not answer the question. Using an inline block can have buggy results, children having strange margins and so on, table is much better.
Setting the height does "prevent" the collapse but it is not a proper fix.
Invalid css
Invalid css never hurt anyone, in fact, it is now the norm. Using browser prefixes is just as invalid as using browser specific hacks and doesn't impact the end user what so ever.
In conclusion
I use both of the above solutions to make elements react correctly and play nicely with each other, I implore you to do the same.
get rid of min-height: 100%. this means that the minimum height of the div is 100% of your browser height. eliminating this should make it fit to the content

CSS fluid layout without tables

Everything online points me to stop using tables, which I've tried my best to do, but I've come across a problem which tables seems to be the only solution for. I have 5 inline-block elements that I want spaced evenly across 100% of the width of the page. I put a width of 20% on the style and set the margin and padding to zero. When I view the page, everything looks pretty good except for the horizontal scrollbar added to the page. If I put these elements in a 100% width table with 5 columns this isn't a problem. In this case do I need to use a table or is there a better solution?
BTW, I've tried this in both Chrome and IE8.
Update: Something I've discovered is that a ~5px gap is being inserted between my elements (found by putting a background-color on them). I have no clue why, as nothing in my styles denotes this:
<div class="links">
Previous
Current
Next
01/01/2011
01/08/2011
</div>
.links
{
white-space: nowrap;
width: 100%;
}
.links a
{
display: inline-block;
width: 20%;
padding: 0;
margin: 0;
color: White;
background-color: #4C8331;
}
Another update:
After JMC Creative pointed out my dumb mistake of putting spaces between the anchors that almost fixed the issue, but now there is one pixel of scrollbar. I see no inherited style that should cause this.
Try putting them in a container. Like so:
#container {
margin: 0;
padding: 0;
width: 100%;
}
#boxes {
float: left;
width: 20%;
}
Your html markup has a space in between the a tags. So therefore it's being rendered as 5 blocks which are 20% wide and 4 spaces of roughly 4px each. So you end up with 100% + 16px.
Edit
In order to solve the scrollbar that is plaguing you in IE, you could set up a conditional comment like so:
<!--[if IE]>
<style type="text/css"> .links { overflow: hidden; } </style>
<![endif]-->
Be sure your body and html set to margin: 0; padding: 0;.
Have you tried using overflow: hidden? Or more specifically overflow-y: hidden?
You want to float your anchors. Doing it this way works for me.
CSS:
.links {
width: 100%;
}
.links>a {
float: left;
display: inline-block;
width: 20%;
padding: 0;
margin: 0;
color: #fff;
background-color: #4C8331;
}
HTML:
<div class="links">
Previous
Current
Next
01/01/2011
01/08/2011
</div>
You may get a scrollbar or see some of the anchors wrapped to another line if there isn't room to fit them all on the page (ie, content overflows the width). I will note that I have seen IE get this wrong and incorrectly wrap when it shouldn't. It seems like a rounding issue and could be worked around.