CSS two divs width 50% in one line with line break in file [duplicate] - css

This question already has answers here:
How to remove the space between inline/inline-block elements?
(41 answers)
Closed 1 year ago.
I want to build a fluid layout using percentages for widths. Here is my HTML:
<div style="width:50%; display:inline-table;">A</div>
<div style="width:50%; display:inline-table;">B</div>
The problem is that the elements won't display together on one line. However, the layout works fine if I remove the line break between the them in the HTML:
<div style="width:50%; display:inline-table;">A</div><div style="width:50%; display:inline-table;">B</div>
What is the problem with the first HTML, above? How can I do something like that, but without using absolute position and float?

The problem is that when something is inline, every whitespace is treated as an actual space. So it will influence the width of the elements. I recommend using float or display: inline-block. (Just don't leave any whitespace between the divs).
Here is a demo:
div {
background: red;
}
div + div {
background: green;
}
<div style="width:50%; display:inline-block;">A</div><div style="width:50%; display:inline-block;">B</div>

The problem is that if you have a new line between them in the HTML, then you get a space between them when you use inline-table or inline-block
50% + 50% + that space > 100% and that's why the second one ends up below the first one
Solutions:
<div></div><div></div>
or
<div>
</div><div>
</div>
or
<div></div><!--
--><div></div>
The idea is not to have any kind of space between the first closing div tag and the second opening div tag in your HTML.
PS - I would also use inline-block instead of inline-table for this

Wrap them around a div with the following CSS
.div_wrapper{
white-space: nowrap;
}

Give this parent DIV font-size:0. Write like this:
<div style="font-size:0">
<div style="width:50%; display:inline-table;font-size:15px">A</div>
<div style="width:50%; display:inline-table;font-size:15px">B</div>
</div>

How can i do something like that but without using absolute position
and float?
Apart from using the inline-block approach (as mentioned in other answers) here are some other approaches:
1) CSS tables (FIDDLE)
.container {
display: table;
width: 100%;
}
.container div {
display: table-cell;
}
<div class="container">
<div>A</div>
<div>B</div>
</div>
2) Flexbox (FIDDLE)
.container {
display: flex;
}
.container div {
flex: 1;
}
<div class="container">
<div>A</div>
<div>B</div>
</div>
For a reference, this CSS-tricks post seems to sum up the various approaches to acheive this.

CSS Flexboxes
Simple modern solution. Better than HTML tables!
.container {
display: flex;
}
.container div {
flex: auto; /* also 1 or 50% */
}
<div class="container">
<div>A</div>
<div>B</div>
</div>
Alternative: CSS Grids
.container {
display: grid;
grid-template-columns: 1fr 1fr; /* also 50% */
}
<div class="container">
<div>A</div>
<div>B</div>
</div>

<div id="wrapper" style="width: 400px">
<div id="left" style="float: left; width: 200px;">Left</div>
<div id="right" style="float: right; width: 200px;">Left</div>
<div style="clear: both;"></div>
</div>
I know this question wanted inline block, but try to view http://jsfiddle.net/N9mzE/1/ in IE 7 (the oldest browser supported where I work). The divs are not side by side.
OP said he did not want to use floats because he did not like them. Well...in my opinion, making good webpages that does not look weird in any browsers should be the maingoal, and you do this by using floats.
Honestly, I can see the problem. Floats are fantastic.

basically inline-table is for element table, I guess what you really need here is inline-block, if you have to use inline-table anyway, try it this way:
<div style="width:50%; display:inline-table;">A</div><!--
--><div style="width:50%; display:inline-table;">B</div>

Sorry but all the answers I see here are either hacky or fail if you sneeze a little harder.
If you use a table you can (if you wish) add a space between the divs, set borders, padding...
<table width="100%" cellspacing="0">
<tr>
<td style="width:50%;">A</td>
<td style="width:50%;">B</td>
</tr>
</table>
Check a more complete example here: http://jsfiddle.net/qPduw/5/

The problem you run into when setting width to 50% is the rounding of subpixels. If the width of your container is i.e. 99 pixels, a width of 50% can result in 2 containers of 50 pixels each.
Using float is probably easiest, and not such a bad idea. See this question for more details on how to fix the problem then.
If you don't want to use float, try using a width of 49%. This will work cross-browser as far as I know, but is not pixel-perfect..
html:
<div id="a">A</div>
<div id="b">B</div>
css:
#a, #b {
width: 49%;
display: inline-block;
}
#a {background-color: red;}
#b {background-color: blue;}

Related

CSS Position element on bottom of container without removing it from flow

I have a container with 3 children elements.
<div class="container">
<img />
<div class="element1"></div>
<div class="element2 bottom"></div>
</div>
They must be positioned as shown on the diagram below:
image is in the top of the left column and nothing goes below it (it is the only element in the left column)
element1 is in the top of the right column
element2 is stick to the bottom of the right column (and must not collide with the element1 which is above it)
Does somebody know how to achieve such layout using pure CSS? Ideally I wouldn't like to add any markup, but I can do that if that's the only possible way.
The biggest problem I'm facing here is how to stick that second element (non-image) to the bottom of the container without removing it from the flow. Because if I use position: absolute and remove it from the flow, the elment above it can collide with it (both elements have unknown height).
Here's a pen to work on: http://codepen.io/anon/pen/yNwGvQ
I would suggest you to use two columns in your html and then use the property display: flex; for your right column as suggested in the article A Complete Guide to Flexbox.
http://codepen.io/AlexisBertin/pen/QboYyY
All the HTML:
<div class="container">
<div class="column column-left">
<div class="image">This is an image</div>
</div>
<div class="column column-right">
<div class="element1">This container has dynamic content so it's height is unknown and may change.<br/><br/> Some random content to make it larger. Some random content to make it larger. Some random content to make it larger. Some random content to make it larger. Some random content to make it larger.</div>
<div class="element2">This container also has dynamic content so it's height is unknown and may change</div>
</div>
</div>
Part of this CSS:
.column {
float: left;
height: 100%;
}
.column.column-left { width: 100px; }
.column.column-right {
width: calc(100% - 100px);
display: flex;
flex-direction: column;
justify-content: space-between;
}
Hope you get the idea. Good Luck'.
EDIT:
The easiest way to achieve this without declaring height to the container seems to only create a third parent div to the first block of the second column and define it as flex: 1; while the second block of this same second column would be define as flex: 0;.
http://codepen.io/anon/pen/yNwZmJ
More details explained in the comments.
The easiest solution I figured out is this one:
First you create this CSS:
.container {
width: 400px;
padding: 10px;
border: 1px solid red;
background-color: white;
}
.container > img {
float: left;
}
.container > div {
position: relative;
overflow: auto;
padding-left: 5px;
min-height: 120px;
}
.container > div > .bottom{
position: absolute;
bottom: 0;
display: block;
}
And then use these divs, depending on your content. The first one you use when you know your text is short:
<div class="container">
<img src="http://placehold.it/120x120">
<div>
<div>
<p>This container has dynamic content so it's height is unknown and may change.</p>
</div>
<div class="bottom">
<p>This container also has dynamic content so it's height is unknown and may change</div>
</div>
</div>
The second one you use when you know your text is long
<div class="container">
<img src="http://placehold.it/120x120">
<div>
<div>
<p>This container has dynamic content so it's height is unknown and may change.</p>
<p>Some random content to make it larger. Some random content to make it larger. Some random content to make it larger. Some random content to make it larger. Some random content to make it larger.</p>
</div>
<div>
<p>This container also has dynamic content so it's height is unknown and may change</p>
</div>
</div>
</div>
The difference is that you remove bottom class from the last div in your div that has long text.
Also in your CSS you can see .container > div{... min-height: 120px; ...}, you should set it to height of your image. In case you want the bottom text more down then you have to increase min-height to be bigger than your image height.
Here is it in action: http://codepen.io/anon/pen/YXgBXx

How to center rows in div with auto overflow

I have a number of "rows" which I want to have grouped together and centered in their container, somethign like this:
However, the number of rows is variable, and if there are enough rows to overflow a set height, I want it to scroll.
The best way I have found to get it to center the rows properly is to use the following css on the container:
.container {
display: table-cell;
vertical-align: middle;
}
However, since the container doesn't have display:block, setting overflow:auto doesn't work. Putting a scrolling div inside the table cell doesn't work either, because the scrolling div needs to have a set height, and that destroys the vertical centering.
After much experimentation, I have finally arrived at the following solution:
html:
<div class="scroll">
<div class="table">
<div class="container">
<div class="row" ></div>
<div class="row" ></div>
...
</div>
</div>
</div>
css:
.scroll {
overflow-y: auto;
height: 80px;
}
.table {
display: table;
height: 100%;
width: 100%;
}
.container {
display: table-cell;
vertical-align: middle;
}
See http://jsfiddle.net/ZCdPG/ for a full implementation.
Although it works, it is unfortunate that it requires three levels of nesting for a single container. Web components would somewhat alleviate this, but the real problem is that there is no real support for vertical centering in CSS, and a common use case can only be achieved with hacks.

Background of a div inside another one with "white-space: nowrap;" does not cover all the width

Ok, I've got a problem out there. To be short, here's a fiddle. I'll repeat myself here:
HTML:
<div class="container">
<div class="selected">
<span>Why don't you cover all the width!?</span>
</div>
<div>
<span>Little content</span>
</div>
</div>
CSS:
.container {
width: 100px;
white-space: nowrap;
background-color: #0f0;
overflow-x: auto;
height: 200px;
}
.selected {
background-color: #f00;
white-space: nowrap;
}
The first question is: why does not the inner div's background cover the entire span?
The second one: I'd like to have a fix, of course.
And one more thing: the html elements are generated by a third-party tool, to which I have no access, which makes "wrapping it all in another div" thing impossible. Only CSS, only hardcore!
UPDATE:
By the way, the container is itself resizable (a frame inside a frameset to be precise).
EDIT:
I've updated the fiddle in order to provide more info. The problem is, that when the second div will be selected, I'd like the red background to stretch to the width of the longest line.
UPDATE 2:
The above described problem can be solved with display: table-row; (see here). The tricky thing is to make this work even if content is less wide than the container itself (a fiddle).
Divs have width:auto by default. So the inner div is 100px wide, like the outer one. The span overflows out of the div.
In this particular case, the easiest solution is to give the inner div display:inline-block
div div {display:inline-block}
so that it no longer fits itself in its parent, but it moulds itself to the width of its contents.
Updated fiddle.
Edit: to answer your second question: yes, the display:inline-block stops the selected div from being as wide as the container.
Fortunately, that can be corrected by adding
min-width:100%;
in addition to the display:inline-block. See more updated fiddle.
Another edit:
And the question keeps changing. Now it's about frames in a frameset. Oh well.
Here is the latest fiddle that solves the problem as formulated now. But let's see what changes the future has in store...
I think you just need to apply the background color to the span instead of the div.
http://jsfiddle.net/M294p/8/
HTML:
<div class="container">
<div class="selected">
<span>Why don't you cover all the width!?</span>
</div>
<div>
<span>Little content</span>
</div>
</div>
CSS:
.container {
width: 100px;
white-space: nowrap;
background-color: #0f0;
overflow-x: auto;
height: 200px;
}
.selected {
background-color: #f00;
white-space: nowrap;
display:inline-block;
}
The answer to your first question is because you have explicit width to the parent div. You can apply display: inline-block to inner div and remove the width: 100px from the parent.
HTML
<div>
<div class="test">
<span>Why don't you cover all the width!?</span>
</div>
</div>
CSS
.test {
background: red;
display: inline-block;
}
An example : http://jsfiddle.net/M294p/6/

Make a child-div the same height like the parent div without position:absolute

Here is the Code:
<div id="content" class="row shadow" >
<div id="test2" class="col-lg-4">
<p>dsfdsfasdfdasfdsafdsfasdf</p>
</div>
<div id="test3" class="col-lg-4" style="">
<p>breerwwerewrqerewrqewqrwqer</p>
</div>
<div id="test4" class="col-lg-4">
<h2>Directlinks</h2>
<p>BRRRRRRRRRRRRRRRRRRRRRRRRRRRR</p>
</div>
</div>
..and i want to set:
border-right:1px solid #ddd;
to id #test2 and #test3
the problem is, that the div don't want to take the height with height:100% from the parent div which is fixed to the content.
if i give one test* an absolute position it takes the max height of the parent div, but i can't set all child div to absolute without destroying the auto fix to the screen for re-sizing.
I added the following code to your example:
#media (min-width: 1200px) {
#content { overflow: hidden; }
#test2, #test3, #test4 {
margin-bottom: -1000px;
padding-bottom: 1000px;
}
}
The padding-bottom: 1000px adds a padding of 1000px to the bottom of each of your columns.
The margin-bottom: -1000px; basically removes this padding again by decreasing the height of each column by 1000px. Each column now has at least 1000px height (the padding + the content).
By giving the #content overflow:hidden you cant see the additional 1000px at the bottom of each column, so the columns seem to have all equal height (try removing the overflow:hidden) to see that they are still different.
The media query (#media (min-width: 1200px)) makes sure to only apply those additional rules when your columns should be displayed next to each other.
Working example: http://jsfiddle.net/R8gH9/3/
The reason it doesn't work is because the parent doesn't have a defined height. Percentage values are based on the explicit height (or width, for that matter) of the parent why nothing happens if you let it flow freely.
Typically, when working with column based layout like this, you can use the display: table and table-cell to achieve what you want. I made a simple example to demonstrate this.
CSS:
.outer {
display: table;
}
.col {
display: table-cell;
border: 1px solid red;
}
HTML:
<div class="outer">
<div class="col">
text<br/>
text<br/>
text<br/>
</div>
<div class="col">
text
</div>
<div class="col">
text<br/>
text<br/>
</div>
</div>
than set it to "position:relative;" or
"position:absolute; display:block;"

How do I get rid of this horizontal scrollbar in Chrome and Safari?

How do i get rid of the horizontal scrollbar on this code: codepen? I'm seeing it in Safari and Chrome, but not Firefox.
I'm using bootstrap, and I've got roughly the following markup:
<div class="container">
<div class="row">
<div class="messages span6 offset1">
<table class="table">
<tbody>
<tr>
<td class=timestamp>[2:22 PM]</td>
<td>echo|</td>
<td>zot: Got a paste or gist of the code?</td>
</tr>
<!-- many more rows… -->
</tbody>
</table>
</div>
</div>
</div>
And styling:
.messages {
height: 200px;
overflow: auto;
}
.messages .timestamp {
min-width: 75px;
}
The problem seems to be the min-width constraint, but I need that to keep the first column from wrapping. I also need to limit the height of messages to 200 pixels. I can't set overflow-x: hidden on .messages because it'll cut off content.
How about this:-
Use word-break on the last column to avoid it cut off.
word-break
Demo
.messages {
height: 200px;
overflow-y: auto;
}
.messages .timestamp {
min-width: 75px;
}
.messages td:nth-child(3) {
word-break:break-all; /* or use word-break:normal; if you don't want to get the word cut in between*/
}
This will adjust the word-break based on the width available, without hiding the contents.
Use the following css:
.messages {
height: 200px;
overflow-y: scroll;
overflow-x: hidden;
}
.messages .timestamp {
min-width: 75px;
}
You could change the height property for .messages to "auto" instead of 200px.
You could increase the width of the table by changing its span6 to a span7, or use a span class to force a width on the message tds that is consistent with the Twitter bootstrap grid structure context.
I couldn't tell you exactly why this is necessary; I actually don't know much about how tables get laid out. But this seems like a solution you could deploy.
A completely alternate thought: why are you using tables to do this? You're not laying out tabular data; you have some semantically related pieces, but they're not tabular in their relationship. Given that, you're breaking one of the cardinal rules: don't use tables for layout! It looks to me like you could probably make this work much more sensibly using div elements, using either float or inline-block with specified widths on them. In that case, your markup would look something like this:
<div class="container">
<div class="row">
<div class="messages span6 offset1">
<div class="message">
<span class="timestamp">[2:22 PM]</div>
<span class="author">echo|</div>
<span class="messageContent">zot: Got a paste or gist of the code?</div>
</div>
<!-- many more rows… -->
</div>
</div>
</div>
Then, your CSS would be fairly straightforward, since you've defined the width value for the span6 (I looked at the actual CSS on the CodePen):
.message {
display: block;
clear: both;
}
.timestamp, .author, .messageContent {
display: inline-block;
vertical-align: top;
}
.timestamp, .author {
width: 75px;
}
.messageContent {
400px; /* You'd obviously need to tweak this down to account for any padding */
}
You shouldn't have the nasty overflow problems, and the divs should fill up their heights in perfectly normal ways. You can also bound them. And there's no overflow issue anymore.
(Perhaps you're where you are because it's something that bootstrap defaults to, in which case: UGH. Break it, or do whatever is necessary to get away from using tables for layout. It will always, always be more pain than it's worth, and it's unsemantic to boot.)

Resources