I'm trying to create a simple (ha) two column layout, where the first column is variable width and the 2nd column is fixed size.
The first column contains a table which works fine except if the td element contains a pre block. In that case, the pre block extends to the 2nd column.
Here is a simple example:
<div class="content">
<div id="Left">
<table id="q-table">
<tr><td>
<div class="q">
<p>This is some paragraph that will be fairly long and wrap.</p>
<pre>This is a very long pre tag that causes headaches.</p>
</div>
<div>
<p>Causes problems if I make class q position: absolute</p>
</div>
</td></tr>
</table>
</div>
<div id="Right">
<p>This is a paragraph on the right with fixed width</p>
</div>
</div>
Here is the CSS style I'm using for this example:
.content {
width: 95%;
position: relative;
}
#Left {
width: 50%;
float: left;
}
#Right {
float: right;
width: 200px;
}
#q-table {
width: 99%;
}
.q {
overflow: auto;
width: 99%
}
If I make the .q class position: absolute then the horizontal flow mostly behaves like I want, but the following div section moves up and messes the vertical alignment.
The pre tag is the culprit. Removing it causes the correct behavior. Unfortunately, pre tags are a necessity.
Think of a StackOverflow layout where a question with code would show up with the scrollbars on a small screen, but if I have a large monitor, the question area would extend and the scrollbars would disappear.
Anyone have any ideas?
Does CSS provide support for what I'd like to do?
This may not provide the desired result. But you can adjust the white-space property instead.
For example, setting it to normal will make it behave like, say, a p tag:
pre {
white-space: normal;
}
See it in action - http://jsfiddle.net/az85F/
Otherwise, set the width and overflow properties. That's what this very forum does for code samples. A quick example - http://jsfiddle.net/mj6Nh/1/
I have come to the conclusion that it is simply not possible to provide the behavior described.
I believe the problem is that the table and the tags conflict with each other.
The table does not enforce the proportional spacing directive when one of the cell element uses a pre tag.
Related
In a page, I have a container of fixed width which contains an inline-block element, followed by some text.
Sometimes, this text will be wider than the container. When this happens, I want it to break to the next line (as seen in the first example below).
Sometimes, this text will also be too wide to display within the container. When this happens, I want the excess to be truncated (overflow: hidden). However, when I try doing this the obvious way, a line break gets inserted after the inline-block element (as seen in the second example).
I can work around this by wrapping the inline-block element and the first letter of the text together in a <nobr> element (as seen in the third example -- or an equivalent white-space:nowrap wrapper), but this seems like a really ugly way of going about things. Is there a better way of doing this?
.container {
outline: 2px solid blue;
width: 150px;
overflow: hidden;
margin: 10px;
}
.inlineblock {
display: inline-block;
width: 30px; height: 1.5em; vertical-align: middle;
background: gray;
}
<div class="container">
<span class="inlineblock"></span>line breaks only at spaces
</div>
<div class="container">
<span class="inlineblock"></span>widetextwidetextwidetext second line
</div>
<div class="container">
<nobr><span class="inlineblock"></span>w</nobr>idetextwidetextwidetext ugly workaround
</div>
It looks like the first character doesn't need to be in the <nobr> element, so this will work:
<nobr><span class="inlineblock"></span></nobr>wide...
Still ugly, but definitely less ugly! It works on Firefox and Chrome at least.
Complete noob here with HTML/CSS.
I'm trying to get something like this : http://imgur.com/Bc72V4M
Here is my code:
<div id="topbar">
<div class="image">
<img src="images/ghwlogo.png">
</div>
<div class="text">
<h1>TEXT TEXT TEXT TEXT TEXT</h1>
</div>
</div>
I've tried floating the div topbar, then display-inline but it never displays horizontally.
I'm so confused. Following tutorials is easy-peasy, but when you need to figure out how to do this yourself, it's completely different.
I think I'm missing a step somewhere. I feel like this should be really easy but it's not.
img {
display: inline;
vertical-align: middle;
}
.subhead {
display: inline;
vertical-align: middle;
}
<div>
<img src="http://dummyimage.com/100x100/000/fff"/>
<h1 class='subhead'>
TEXT
</h1>
</div>
I removed some HTML; I only add more when I can't think of how to get the effect with just CSS. You can add some back, but you may have to set display: inline on some inner elements then.
Generally, a few different ways of putting elements horizontally:
Floating: Removes it from standard flow layout, and may interfere with the root element's total height. Was previously the preferred method of placement but I feel like there are better alternatives.
Display Inline: Treats an element a bit like text. Cannot have a custom height or various other attributes.
Display Inline-Block: Often a "fix-all" for me when I want something laid out horizontally, but to have other styling aspects like height, border, etc.
Position Absolute: You can make a higher element a "relative element" for absolute positioning by setting position: relative on it. Like floating this takes it out of layout, but it can even overlap elements; useful for certain things. Don't rely on absolute pixel amounts too much.
In my case, once things are laid out horizontally, vertical alignment is the next issue. Remember that adding content could make this block very very tall, so you can't just say "vertical-align to the bottom of the thing". Think of all elements in the div as simply letters in a paragraph; for the smaller ones, you're telling it how to align that one letter. For the biggest ones, you're telling it where that "letter" is aligned compared to the others. So, it's important to set vertical alignment how you want it on the image as well.
EDIT: updated answer per #Katana314 answer. I've maintained the OP's markup.
#topbar {
width: 100%;
overflow: hidden;
}
.image {
display: inline-block;
vertical-align: middle;
border: 5px solid black;
height: 100px;
width: 100px;
}
.text {
display: inline-block;
vertical-align: middle;
}
Fiddle: https://jsfiddle.net/dgautsch/che0dtfk/
You could make the image and the text a separate div and then have both of them under the inline-block attribute. The text div would need to have a position: absolute attribute, though, for formatting purposes.
After viewing the Fiddle, you can adjust the left position attribute accordingly to generate space. Here is the link: https://jsfiddle.net/kuLLd866/.
HTML:
<body>
<div class="image">
<img src="http://gfx2.poged.com/poged/game_logo_default_fix.png?2492">
</div>
<div class="imagetext">
<h1>Text text text</h1>
</div>
</body>
CSS:
.image {
display: inline-block;
}
.imagetext {
position: absolute;
top: 50px;
display: inline-block;
}
I have a situation where I have a layout like in the following fiddle:
<div>
<span style="float:left;">This is a longer text that could potentially split into more than one line.</span>
<span style="float:right;">Force this text into one line.</span>
</div>
jsfiddle demo.
What I am trying to accomplish is that the right span adjusts size so it's as small as possible but fits its content in one line. The left span should adjust to the rest of the main div size and can break text into as many lines as needed.
Restrictions:
Content is variable for both spans. The left one is potentially unlimited, the right one will never take more than about 30% of the screen.
I would really like a pure css/html solution. With Javascript I know how to do it, but it would make it harder to mantain, thus I am exploring something cleaner.
First line of the left span should always be on the same line as the first line of the right one.
How can I do this?
Method #1
If you don't want to specify an explicit width, you can use display: table; for the left span:
.left {
display: table;
background-color: orange; /*Just for demo */
}
.right {
float: right;
white-space: nowrap;
background-color: gold; /*Just for demo */
}
JSFiddle Demo.
Method #2
Also, you can display the left span as a block level element and hide the horizontal overflow by overflow-x: hidden; as follows:
.left {
display: block;
overflow-x: hidden;
}
Updated Demo.
apply width property to both span
<span style="float:left; width:50%;">This is a longer text that could potentially split into more than one line.</span>
<span style="float:right; width:50%;">Force this text into one line.</span>
or see here http://jsfiddle.net/pE2c8/4/, you can understand.
An easy way of doing this is to switch the 2 spans around in your HTML. Add width 100% to the span that should break up, and float right to the full width span.
HTML
<html>
<div>
<span style="float:right;">Force this text into one line.asdsadsadasdsasadsad asd</span>
<span style="width:100%;">This is a longer text that could potentially split into more than one line. </span>
</div>
</html>
FIDDLE
http://jsfiddle.net/pE2c8/6/
I don't think you can get away with achieving this without specifying at least some kind of width properties for your two spans, as you need some way of saying where the first container should break its lines. In this case you knowing that the second container won't take up more than about 30% might be useful.
Fiddle
By using max-width:
.left {
float: left;
max-width: 70%;
}
.right {
float: right;
max-width: 30%;
/* Can add the following for good measure
(will keep on one line even if over 30% wide
and hides the excess) */
white-space: nowrap;
overflow: hidden;
}
i have a header, which takes the whole width of the screen. in my header i want to place 3 divs, which should be aligned next to each other. the div's on the side being fixed-width, and the middle should take the other space available. so i don't know the width of the header, and i don't know the width of the middle container.
right now i have this code:
html:
<div id="header">
<div id="menu-container">
menu goes here
</div>
<div id="logo-container">
logo goes here
</div>
<div id="music-player-container">
music player comes here
</div>
</div>
and css:
#header {
height: 200px;
margin: 0;
padding: 0;
border: 0;
}
#menu-container {
width: 400px;
height: inherit;
float: left;
}
#logo-container {
height: 100%;
background-image: url('../images/logo.png');
background-repeat: no-repeat;
background-position: center;
float: left;
width: auto;
}
#music-player-container {
width: 400px;
height: inherit;
float: left;
}
which should be working according to other problems with the float.... it doesn't
You can use floated divs with negative margins:
http://jsfiddle.net/cy5E7/1/
In your case:
http://jsfiddle.net/AjVHy/
Negative margins are better then just left/right float fixed divs. We don't get messed layout if user have very small window. Look at this bad example (resize browser window to small width): http://jsfiddle.net/surendraVsingh/qZLHb/1/ (thanks to #SVS). In normal float layout, all floated divs are on place only if parent container is wide enough.
Another disadvantage of standard float layout is when we want column layout but we don't know height of middle content, look like it can look
float layout, dynamic content height
negative margins layout, dynamic content height
Switch the order of your second and third divs then use this CSS.
#menu-container, #music-player-container {
float:left;
width: 400px;
}
#music-player-container {
float:right;
}
#logo-container {
margin:0 400px;
}
jsfiddle example
I'm not exactly sure of what you are planning to code up, but in my perspective, I see it like this: "You want to have 3 columns, column 1 being of a fixed with, column 2 a fluid width and column 3 yet again of fixed width."
What I fail to understand here is that, in the case of a really small width monitor (like a 1024x768 resolution, for instance), having a 400px column on both sides would leave you with just 224px of logo space. It would look un-natural.
Anyways, if you would still like to continue, I suggest you enclose all the three divs [menu-container, logo-container & music-player-container] inside another element called header (If you're using HTML5) or another div with any name you like (If you're using <= HTML 4.01) and then fix it's width to 100%; and a fixed height of 200px;.
Then let the menu-container, float: left; and the music-player-container float: right;. This will give space to the logo-container. Let the logo-container have a width: auto;. Having done this will give you a basic semi-fluid header layout, if I'm right.
Cheers, hope your question gets solved quick :)
I understand what you're trying to do, and I am sorry to say that I have yet to find a solution for this issue without using some ugly form of JavaScript/jQuery.
Essentially, the problem is that CSS does not have any properties (not even when fiddling with display properties) that will allow you to have two elements, one with fixed width and the other taking up the remainder of the space in the div. There are some options with float that can allow you to very closely simulate this, but I can tell you that they are unlikely to give you what you really want.
There is a resource out there, a project called Bootstrap, that you can install like any other jQuery plugin (or you can actually use it like a "CSS" plugin - you'll see what I mean - if you don't want the JavaScript), that will enable you to do what you want.
Here is the link: http://twitter.github.com/bootstrap/download.html
I strongly recommend that you review the documentation first to make sure you are aware of any caveats/limitations.
Good Luck!
EDIT: I like rogal's answer, but before using it you should bear in mind that doing so removes your ability to add a left border and makes it very difficult to apply background images to the div with the negative margin.
another option:
#header {
display: table;
height: 200px;
margin: 0;
padding: 0;
border: none;
}
#header > div {
display: table-cell;
height: inherit;
}
#menu-container, #music-player-container {
width: 400px;
}
#logo-container {
background-image: url('../images/logo.png');
background-repeat: no-repeat;
background-position: center;
}
HTH
You could of course use a table..
-hides-
Something like this inside the header div:
<table width=100%>
<tr>
<td width=200>
menu
</td>
<td>
logo
</td>
<td width=400>
music
</td>
</tr>
</table>
(too lazy for CSS atm)
Can't think of a very good way to do this. Not an ideal solution, but you could turn this into a table.
<table>
<tr>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
</tr>
</table>
Then you can just set the dimensions of the div and the td that contains it to be the same.
I am trying to lay out a table-like page with two columns. I want the rightmost column to dock to the right of the page, and this column should have a distinct background color. The content in the right side is almost always going to be smaller than that on the left. I would like the div on the right to always be tall enough to reach the separator for the row below it. How can I make my background color fill that space?
.rightfloat {
color: red;
background-color: #BBBBBB;
float: right;
width: 200px;
}
.left {
font-size: 20pt;
}
.separator {
clear: both;
width: 100%;
border-top: 1px solid black;
}
<div class="separator">
<div class="rightfloat">
Some really short content.
</div>
<div class="left">
Some really really really really really really
really really really really big content
</div>
</div>
<div class="separator">
<div class="rightfloat">
Some more short content.
</div>
<div class="left">
Some really really really really really really
really really really really big content
</div>
</div>
Edit: I agree that this example is very table-like and an actual table would be a fine choice. But my "real" page will eventually be less table-like, and I'd just like to first master this task!
Also, for some reason, when I create/edit my posts in IE7, the code shows up correctly in the preview view, but when I actually post the message, the formatting gets removed. Editing my post in Firefox 2 seems to have worked, FWIW.
Another edit: Yeah, I unaccepted GateKiller's answer. It does indeed work nicely on my simple page, but not in my actual heavier page. I'll investigate some of the links y'all have pointed me to.
Ahem...
The short answer to your question is that you must set the height of 100% to the body and html tag, then set the height to 100% on each div element you want to make 100% the height of the page.
Actually, 100% height will not work in most design situations - this may be short but it is not a good answer. Google "any column longest" layouts. The best way is to put the left and right cols inside a wrapper div, float the left and right cols and then float the wrapper - this makes it stretch to the height of the inner containers - then set background image on the outer wrapper. But watch for any horizontal margins on the floated elements in case you get the IE "double margin float bug".
Give this a try:
html, body,
#left, #right {
height: 100%
}
#left {
float: left;
width: 25%;
}
#right {
width: 75%;
}
<html>
<body>
<div id="left">
Content
</div>
<div id="right">
Content
</div>
</body>
</html>
Some browsers support CSS tables, so you could create this kind of layout using the various CSS display: table-* values. There's more information on CSS tables in this article (and the book of the same name) by Rachel Andrew: Everything You Know About CSS is Wrong
If you need a consistent layout in older browsers that don't support CSS tables, you need to do two things:
Make your "table row" element clear its internal floated elements.
The simplest way of doing this is to set overflow: hidden which takes care of most browsers, and zoom: 1 to trigger the hasLayout property in older versions of IE.
There are many other ways of clearing floats, if this approach causes undesirable side effects you should check the question which method of 'clearfix' is best and the article on having layout for other methods.
Balance the height of the two "table cell" elements.
There are two ways you could approach this. Either you can create the appearance of equal heights by setting a background image on the "table row" element (the faux columns technique) or you can make the heights of the columns match by giving each a large padding and equally large negative margin.
Faux columns is the simpler approach and works very well when the width of one or both columns is fixed. The other technique copes better with variable width columns (based on percentage or em units) but can cause problems in some browsers if you link directly to content within your columns (e.g. if a column contained <div id="foo"></div> and you linked to #foo)
Here's an example using the padding/margin technique to balance the height of the columns.
html, body {
height: 100%;
}
.row {
zoom: 1; /* Clear internal floats in IE */
overflow: hidden; /* Clear internal floats */
}
.right-column,
.left-column {
padding-bottom: 1000em; /* Balance the heights of the columns */
margin-bottom: -1000em; /* */
}
.right-column {
width: 20%;
float: right;
}
.left-column {
width: 79%;
float: left;
}
<div class="row">
<div class="right-column">Right column content</div>
<div class="left-column">Left column content</div>
</div>
<div class="row">
<div class="right-column">Right column content</div>
<div class="left-column">Left column content</div>
</div>
This Barcamp demo by Natalie Downe may also be useful when figuring out how to add additional columns and nice spacing and padding: Equal Height Columns and other tricks (it's also where I first learnt about the margin/padding trick to balance column heights)
I gave up on strictly CSS and used a little jquery:
var leftcol = $("#leftcolumn");
var rightcol = $("#rightcolumn");
var leftcol_height = leftcol.height();
var rightcol_height = rightcol.height();
if (leftcol_height > rightcol_height)
rightcol.height(leftcol_height);
else
leftcol.height(rightcol_height);
Here's an example of equal-height columns - Equal Height Columns - revisited
You can also check out the idea of "Faux Columns" as well - Faux Columns
Don't go the table route. If it's not tabular data, don't treat it as such. It's bad for accessibility and flexibility.
I had the same problem on my site (shameless plug).
I had the nav section "float: right" and the main body of the page has a background image about 250px across aligned to the right and "repeat-y". I then added something with "clear: both" to it. Here is the W3Schools and the CSS clear property.
I placed the clear at the bottom of the "page" classed div. My page source looks something like this.
body
-> header (big blue banner)
-> headerNav (green bar at the top)
-> breadcrumbs (invisible at the moment)
-> page
-> navigation (floats to the right)
-> content (main content)
-> clear (the quote at the bottom)
-> footerNav (the green bar at the bottom)
-> clear (empty but still does something)
-> footer (blue thing at the bottom)
I hope that helps :)
No need to write own css, there is an library called "Bootstrap css" by calling that in your HTML head section, we can achieve many stylings,Here is an example:
If you want to provide two column in a row, you can simply do the following:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div class="row">
<div class="col-md-6">Content</div>
<div class="col-md-6">Content</div>
</div>
Here md stands for medium device,,you can use col-sm-6 for smaller devices and col-xs-6 for extra small devices
The short answer to your question is that you must set the height of 100% to the body and html tag, then set the height to 100% on each div element you want to make 100% the height of the page.
A 2 column layout is a little bit tough to get working in CSS (at least until CSS3 is practical.)
Floating left and right will work to a point, but it won't allow you to extend the background. To make backgrounds stay solid, you'll have to implement a technique known as "faux columns," which basically means your columns themselves won't have a background image. Your 2 columns will be contained inside of a parent tag. This parent tag is given a background image that contains the 2 column colors you want. Make this background only as big as you need it to (if it is a solid color, only make it 1 pixel high) and have it repeat-y. AListApart has a great walkthrough on what is needed to make it work.
http://www.alistapart.com/articles/fauxcolumns/
I can think of 2 options
Use javascript to resize the smaller column on page load.
Fake the equal heights by setting the background-color for the column on the container <div/> instead (<div class="separator"/>) with repeat-y
Just trying to help out here so the code is more readable.
Remember that you can insert code snippets by clicking on the button at the top with "101010". Just enter your code then highlight it and click the button.
Here is an example:
<html>
<body>
<style type="text/css">
.rightfloat {
color: red;
background-color: #BBBBBB;
float: right;
width: 200px;
}
.left {
font-size: 20pt;
}
.separator {
clear: both;
width: 100%;
border-top: 1px solid black;
}
</style>
This should work for you: Set the height to 100% in your css for the html and body elements. You can then adjust the height to your needs in the div.
html {
height: 100%;
}
body {
height: 100%;
}
div {
height: 100%; /* Set Div Height */
}
It's enough to just use the css property width to do so.
Here is an example:
<style type="text/css">;
td {
width:25%;
height:100%;
float:left;
}
</style>
.rightfloat {
color: red;
background-color: #BBBBBB;
float: right;
width: 200px;
}
.left {
font-size: 20pt;
}
.separator {
clear: both;
width: 100%;
border-top: 1px solid black;
}
<div class="separator">
<div class="rightfloat">
Some really short content.
</div>
<div class="left">
Some really really really really really really
really really really really big content
</div>
</div>
<div class="separator">
<div class="rightfloat">
Some more short content.
</div>
<div class="left">
Some really really really really really really
really really really really big content
</div>
</div>