Two column layout with left fluid and right fill the rest width - html

I need something similar to this and this. However I want the right column not to be fixed size, but variable size. Is it possible?
–––––––––––––––––––––––––––––––––––––––––––––––––––––––
|some text|stretch to fill the remaining space | <- viewport
–––––––––––––––––––––––––––––––––––––––––––––––––––––––

This is the float solution. You can set a fixed width to .one column, or leave as it is to let the content to decide. And set overflow: auto; or overflow: hidden; to .two column.
.one {
float: left;
background: aqua;
}
.two {
overflow: auto;
background: yellow;
}
<div class="one">hello</div>
<div class="two">world</div>
The flexbox solution. The key is to set flex: 1; aka flex-grow: 1; to the dynamic width column. Follow this to see the browser support tables.
body {
display: flex;
}
.one {
background: aqua;
}
.two {
flex: 1;
background: yellow;
}
<div class="one">hello</div>
<div class="two">world</div>

http://jsfiddle.net/A8zLY/2333/
Fiddle from link I posted.
right does not need fixed width. See link above
width:auto
Is this what you're looking for?

Maybe missing something but couldn't this be used for each item?
<div>
<span>left text<span/><span>right text<span/>
</div>

If a two-column-ish button is what you are after... (your ascii screenshot looks like this), so: diving the space in the best way but with one side winning, if it gets tight ➝ no truncated price, but truncated label if it has to be... ➪ full source on codepen
<div class="container">
<div class="two">125 €</div>
<div class="one">my favorite provider</div>
</div>
CSS (stylus)
.container
clearfix()
border 2px solid purple
.one, .two
padding 4px
.two
background #aca
float right
white-space nowrap
text-overflow ellipsis
.one
background #caa
overflow hidden
white-space nowrap
text-overflow ellipsis

Related

How do I set the width of a DIV to match its content

How do I set the width of a div if I want it to be exactly as wide as its contents are. However, I have many children in my DIV that inevitable collapse because they take up more horizontal space than the div allows.
I have this CSS:
.outer{
width: 100%;
background-color: green;
}
.inner{
width: auto;
display: inline-block;
margin: 0 auto;
background-color: red;
}
.row{
float: left;
width: 250px;
background-color: blue;
display: inline-block;
}
And this is my HTML:
<div class="outer">
<div class="inner">
<div class="row">asd1</div>
<div class="row">asd2</div>
<div class="row">asd3</div>
<div class="row">asd4</div>
</div>
<div class="clear"></div>
</div>
Here is my jsfiddle: http://jsfiddle.net/vullnetyy/pshao68g/
What I want to do here is:
the red div must be exactly as wide as the 3 blue divs in its first row
the red div must be centered within the green div
javascript must be avoided
no static width may be set to the red or green divs (because this is supposed to be responsive, and an arbitrary number of blue divs may be provided)
First of all, if you want to center an Element you need to make it:
display: block;
width : %/px;
margin-left: auto;
margin-right:auto;
If you want the 3 blue divs to be inside of the red div and to be exactly 3 blue = 1red width, give each blue 33.333% width.
such as in this example: https://jsfiddle.net/vullnetyy/pshao68g/
Theres two conflicting issues here.
1)You must have a set width in order to do margin-left/right auto.
2)If you float to try to match child width you cant do margin auto. Now I know you didnt put float left on inner. But you did do display:inline-block which has float left and a few other rules attached.
In this particular case, you have to compromise just a little to get the results you want. Simply set .inner to the same as the row aka 250px since we know thats how large the child will be, and remove display:inline-block and PRESTO!
try this for to your inner and see what happens.
.inner{
width: 250px;
margin: 0 auto;
background-color: red;
}

Make element scale down to min-width before next elements wrap

I am making a fairly simple responsive website. I have a logo div that keeps the logo centered on small screens, and to the left on big screens. Everything is working how I want it to, (try resizing the jsfiddle) except that I want the logo div to scale down to it's min-width before the links wrap to the next line. I'm not sure how to word this, but I want the logo div to resize based on if the links are pushing it (if they have enough room). When it reaches it's min-width, then the links should wrap. Not sure if this is possible, but I figured I'd ask anyway.
Here is the jsfiddle.
The html:
<div class="header">
<div class="logo">logo</div>
<div class="link">link one</div>
<div class="link">link two</div>
<div class="link">link three</div>
</div>
The css:
.header {
text-align: center; /* Centers the logo text, and centers the links between the logo div and the other side of the page.*/
}
.logo {
max-width: 300px;
min-width: 100px;
width: 100%; /* It is always the min-width without this*/
background-color: red;
display: inline-block;
float: left;
}
.link {
display: inline-block;
background-color: green;
}
I hope I was clear, I'm still learning. Let me know if I need to add any more details.
I went looking some more and found flexboxes. Got them to do exactly what I wanted.
http://jsfiddle.net/3525C/10/
My new HTML:
<div class="header">
<div class="logo">logo</div>
<div class="nav">
<div class="link">link one</div>
<div class="link">link two</div>
<div class="link">link three</div>
</div>
</div>
and CSS:
.header {
text-align: center;
display: flex;
flex-flow: row wrap;
}
.logo {
flex: 1 0 auto;
min-width: 100px;
background-color: red;
}
.nav {
flex: 1 1 auto;
background-color: lightgray;
text-align: center;
}
.link {
display: inline-block;
background-color: green;
}
Thanks hexalys for helping me get it working.
The only real thing that responds the way you're talking is a table. Table cells have the capability of being flexible with their width.
You can use CSS to make this happen. It's a more modern display, so not all browsers (looking at you, older IE) will support it. But this should get you started: http://jsfiddle.net/mfvf8/
Here's what I added as a proof of concept:
.header
{
display: table;
width: 100%;
}
.header > div
{
display: table-cell;
}
.header .link
{
white-space: nowrap;
width: 1px;
}
I set the header to be displayed as a table, and gave it full width. I made all of the child divs act like a table cell. I made the links minimum width (1px) and said not to wrap whitespace. With regular divs, that would overflow. With table cells, that means it tries to be 1px wide but will expand to fit its content.
The rest of a table row's width will go evenly to whichever cells are left over that don't have a set width. In this case, it's the logo div. Then, as you shrink the window, it will slowly start to shrink the logo as needed.
You will need to tweak this to fit your design better. If you don't want your nav pushed all the way to the right like it is in the jsfiddle, you might need a "buffer" div to the far right, or different width settings, or a set max-width on the header div.

display only first div tag inside main div

I have four div tags. One of them is .main div. The rest of the are inside .main with .sub classes. What I want is first to show 1st div tag inside .main and the rest will be placed on the right side of the first div tag but the overflow of the main div tag is hidden so that the other two div tags are not shown only the first is visible. I am trying to achieve this with this code. How can I achieve this?
.main {
width: 100%;
height: 500px;
background: red;
overflow: hidden;
}
.sub {
width: 100%;
height: 300px;
float: left;
}
.blue { background: lightblue; }
.green { background: green; }
.orange { background: orange; }
Assuming I've understood you correctly, and you want to see all three sub divs, one on the left, and two on the right, the problem is that you've set the widths to 100%, so there is no space to have them floating next to each other.
You need to set their widths so that they don't take up the full width of the container, for example they can each be 50% wide.
You also need to set the heights of the two divs on the right so that their total height is the same as the div on the left if you want them to line up.
Update:
To make it so that only the left div is visible initially, I think it's best you add another wrapper div around the the sub divs like this:
<div class="main">
<div class="wrapper">
<div class="sub blue"></div>
<div class="sub green"></div>
<div class="sub orange"></div>
</div>
</div>
With a width set to 200%.
.wrapper {
width:200%;
}
Then when you want the right hand divs to become visible, you can slide them onto the screen by repositioning the wrapper div, either with a transform, relative position, or margin setting.
Updated fiddle example
I don't know why but i have found that if you have space below the first item in this situation it won't work as expected..
so make the height of sub match then it will work:
.sub {
width: 100%;
height: 500px;
float: left;
}
http://jsfiddle.net/Ex9EC/2/
probably this is totally wrong approach though so wait for someone who knows to comment maybe?
Also I think there might be something about how the position of the outer/container div has to be set (to relative,absolute or fixed) which is why i added that but it seems to work without it too:
http://jsfiddle.net/Ex9EC/3/

2 divs aligned side by side, how to make right div fill width 100%?

I'm wondering what the best way to go about doing this is...
I have 3 divs:
a div#container with width=100%; that holds 2 inner divs
a div#inner_left with width changing dynamically, but no wider than 200px (will hold a product image)
an div#inner_right where the width should fill the rest of the space in the container (will contain text to describe the product shown)
#container {
width:100%
}
#inner_left {
display:inline-block:
max-width:200px;
}
#inner_right {
display:inline-block;
width:100%;
}
The problem is that the div#inner_right creates a line break and fills the entire width. How can I make them align next to each other, with the right div accounting for the width taken by the left div (which changes dynamically?). I've gotten this to work other ways, but I'm looking for a clean solution...
Any help for a CSS noob is much appreciated!
I haven't really seen a good solution in the answers here. So I'll share mine.
Best way to do this is by using the table-cell option in CSS. One important thing to add is a 'min-width' to the element that has a pixel width.
Example:
<div id="left">
Left
</div>
<div id="right">
right
</div>
CSS:
#left {
display: table-cell;
min-width: 160px;
}
#right {
display: table-cell;
width: 100%;
vertical-align: top;
}
Have a look at "liquid layouts" it can describe what you're talking about.
You're probably looking for this one.
In your example, try setting your display to inline. However, you won't technically be able to use block level elements in it, so have a look at the links I posted above. :)
The problem with setting the width to 100% if you're using floats is that it is considered 100% of the container, so it won't work either since the 100% includes the left div's width.
Edit: Here is the example of the other answer, I've edited it to include the html/css from the example site above for simplicity's sake.
I'll also include it below:
HTML
<div id="contentwrapper">
<div id="contentcolumn">
<div class="innertube"><b>Content Column: <em>Fluid</em></b></div>
</div>
</div>
<div id="leftcolumn">
<div class="innertube"><b>Left Column: <em>200px</em></b></div>
</div>
CSS
#contentwrapper{
float: left;
width: 100%;
}
#contentcolumn{
margin-left: 200px; /*Set left margin to LeftColumnWidth*/
}
#leftcolumn{
float: left;
width: 200px; /*Width of left column*/
margin-left: -100%;
background: #C8FC98;
}
This can be accomplished using Flex-Box, which has been introduced with CSS3 and according to Can I use is cross-browser.
.container {
display: flex;
}
.left {
width: 100px; /* or leave it undefined */
}
.right {
flex-grow: 1;
}
/* some styling */
.container {height: 90vh}
.left {background: gray}
.right {background: red}
<div class="container">
<div class="left">100px</div>
<div class="right">Rest</div>
</div>
So even though I wanted to do this with CSS only, I ended up just using tables...
Use floating:
#container{
width:100%
}
#inner_left{
float:left;
max-width:200px;
}
#inner_right{
float:left;
width:100%;
}
Edit: have a read a this, it's a nice little guide : quirksmode
you need to provide position:absolute style property to both your div's
This is based on #w00 's answer. +1 friend.
My situation was when I wanted to show a couple of icons next to a label. I use the fluid class for that which is where the nowrap comes in. This is so the icons appear on the same line.
.sidebyside-left-fixed, .sidebyside-right-fixed
{
display: table-cell;
width: 100%;
}
.sidebyside-left-fluid , .sidebyside-right-fluid
{
display: table-cell;
vertical-align: top;
white-space: nowrap;
}
Here is an easy method to achieve this, and this is something that's quite frequently needed. It's also tested to works with all browsers, including the very old ones (let me know if it doesn't on any).
Link to a sample: https://jsfiddle.net/collinsethans/jdgduw6a/
Here's the HTML part:
<div class="wrapper">
<div class="left">
Left Box
</div>
<div class="right">
Right Box
</div>
</div>
And the corresponding SCSS:
.wrapper {
position: relative;
}
$left_width: 200px;
.left {
position: absolute;
left: 0px;
width: $left_width;
}
.right {
margin-left: $left_width;
}
If you are not using any CSS preprocessors, then replace the $left_width with your value (200px here).
Credit: This is based on http://htmldog.com/examples/pagelayout2/.
There are several other useful ones there.

How can I expand floated child div's height to parent's height?

I have the page structure as:
<div class="parent">
<div class="child-left floatLeft">
</div>
<div class="child-right floatLeft">
</div>
</div>
Now, the child-left DIV will have more content, so the parent DIV's height increases as per the child DIV.
But the problem is child-right height is not increasing. How can I make its height as equal to it's parent?
For the parent element, add the following properties:
.parent {
overflow: hidden;
position: relative;
width: 100%;
}
then for .child-right these:
.child-right {
background:green;
height: 100%;
width: 50%;
position: absolute;
right: 0;
top: 0;
}
Find more detailed results with CSS examples here and more information about equal height columns here.
A common solution to this problem uses absolute positioning or cropped floats, but these are tricky in that they require extensive tuning if your columns change in number+size, and that you need to make sure your "main" column is always the longest. Instead, I'd suggest you use one of three more robust solutions:
display: flex: by far the simplest & best solution and very flexible - but unsupported by IE9 and older.
table or display: table: very simple, very compatible (pretty much every browser ever), quite flexible.
display: inline-block; width:50% with a negative margin hack: quite simple, but column-bottom borders are a little tricky.
1. display:flex
This is really simple, and it's easy to adapt to more complex or more detailed layouts - but flexbox is only supported by IE10 or later (in addition to other modern browsers).
Example: http://output.jsbin.com/hetunujuma/1
Relevant html:
<div class="parent"><div>column 1</div><div>column 2</div></div>
Relevant css:
.parent { display: -ms-flex; display: -webkit-flex; display: flex; }
.parent>div { flex:1; }
Flexbox has support for a lot more options, but to simply have any number of columns the above suffices!
2.<table> or display: table
A simple & extremely compatible way to do this is to use a table - I'd recommend you try that first if you need old-IE support. You're dealing with columns; divs + floats simply aren't the best way to do that (not to mention the fact that multiple levels of nested divs just to hack around css limitations is hardly more "semantic" than just using a simple table). If you do not wish to use the table element, consider css display: table (unsupported by IE7 and older).
Example: http://jsfiddle.net/emn13/7FFp3/
Relevant html: (but consider using a plain <table> instead)
<div class="parent"><div>column 1</div><div>column 2</div></div>
Relevant css:
.parent { display: table; }
.parent > div {display: table-cell; width:50%; }
/*omit width:50% for auto-scaled column widths*/
This approach is far more robust than using overflow:hidden with floats. You can add pretty much any number of columns; you can have them auto-scale if you want; and you retain compatibility with ancient browsers. Unlike the float solution requires, you also don't need to know beforehand which column is longest; the height scales just fine.
KISS: don't use float hacks unless you specifically need to. If IE7 is an issue, I'd still pick a plain table with semantic columns over a hard-to-maintain, less flexible trick-CSS solution any day.
By the way, if you need your layout to be responsive (e.g. no columns on small mobile phones) you can use a #media query to fall back to plain block layout for small screen widths - this works whether you use <table> or any other display: table element.
3. display:inline block with a negative margin hack.
Another alternative is to use display:inline block.
Example: http://jsbin.com/ovuqes/2/edit
Relevant html: (the absence of spaces between the div tags is significant!)
<div class="parent"><div><div>column 1</div></div><div><div>column 2</div></div></div>
Relevant css:
.parent {
position: relative; width: 100%; white-space: nowrap; overflow: hidden;
}
.parent>div {
display:inline-block; width:50%; white-space:normal; vertical-align:top;
}
.parent>div>div {
padding-bottom: 32768px; margin-bottom: -32768px;
}
This is slightly tricky, and the negative margin means that the "true" bottom of the columns is obscured. This in turn means you can't position anything relative to the bottom of those columns because that's cut off by overflow: hidden. Note that in addition to inline-blocks, you can achieve a similar effect with floats.
TL;DR: use flexbox if you can ignore IE9 and older; otherwise try a (css) table. If neither of those options work for you, there are negative margin hacks, but these can cause weird display issues that are easy to miss during development, and there are layout limitations you need to be aware of.
For the parent:
display: flex;
For children:
align-items: stretch;
You should add some prefixes, check caniuse.
I found a lot of answers, but probably the best solution for me is
.parent {
overflow: hidden;
}
.parent .floatLeft {
# your other styles
float: left;
margin-bottom: -99999px;
padding-bottom: 99999px;
}
You can check other solutions here http://css-tricks.com/fluid-width-equal-height-columns/
Please set parent div to overflow: hidden
then in child divs you can set a large amount for padding-bottom. for example
padding-bottom: 5000px
then margin-bottom: -5000px
and then all child divs will be the height of the parent.
Of course this wont work if you are trying to put content in the parent div (outside of other divs that is)
.parent{
border: 1px solid black;
overflow: hidden;
height: auto;
}
.child{
float: left;
padding-bottom: 1500px;
margin-bottom: -1500px;
}
.child1{
background: red;
padding-right: 10px;
}
.child2{
background: green;
padding-left: 10px;
}
<div class="parent">
<div class="child1 child">
One line text in child1
</div>
<div class="child2 child">
Three line text in child2<br />
Three line text in child2<br />
Three line text in child2
</div>
</div>
Example: http://jsfiddle.net/Tareqdhk/DAFEC/
Does the parent have a height? If you set the parents height like so.
div.parent { height: 300px };
Then you can make the child stretch to the full height like this.
div.child-right { height: 100% };
EDIT
Here is how you would do it using JavaScript.
CSS table display is ideal for this:
.parent {
display: table;
width: 100%;
}
.parent > div {
display: table-cell;
}
.child-left {
background: powderblue;
}
.child-right {
background: papayawhip;
}
<div class="parent">
<div class="child-left">Short</div>
<div class="child-right">Tall<br>Tall</div>
</div>
Original answer (assumed any column could be taller):
You're trying to make the parent's height dependent on the children's height and children's height dependent on parent's height. Won't compute. CSS Faux columns is the best solution. There's more than one way of doing that. I'd rather not use JavaScript.
I used this for a comment section:
.parent {
display: flex;
float: left;
border-top:2px solid black;
width:635px;
margin:10px 0px 0px 0px;
padding:0px 20px 0px 20px;
background-color: rgba(255,255,255,0.5);
}
.child-left {
align-items: stretch;
float: left;
width:135px;
padding:10px 10px 10px 0px;
height:inherit;
border-right:2px solid black;
}
.child-right {
align-items: stretch;
float: left;
width:468px;
padding:10px;
}
<div class="parent">
<div class="child-left">Short</div>
<div class="child-right">Tall<br>Tall</div>
</div>
You could float the child-right to the right, but in this case I've calculated the widths of each div precisely.
I have recently done this on my website using jQuery. The code calculates the height of the tallest div and sets the other divs to the same height. Here's the technique:
http://www.broken-links.com/2009/01/20/very-quick-equal-height-columns-in-jquery/
I don't believe height:100% will work, so if you don't explicitly know the div heights I don't think there is a pure CSS solution.
If you are aware of bootstrap you can do it easily by using 'flex' property.All you need to do is pass below css properties to parent div
.homepageSection {
overflow: hidden;
height: auto;
display: flex;
flex-flow: row;
}
where .homepageSection is my parent div.
Now add child div in your html as
<div class="abc col-md-6">
<div class="abc col-md-6">
where abc is my child div.You can check equality of height in both child div irrespective of border just by giving border to child div
<div class="parent" style="height:500px;">
<div class="child-left floatLeft" style="height:100%">
</div>
<div class="child-right floatLeft" style="height:100%">
</div>
</div>
I used inline style just to give idea.
I can see that the accepted answer uses position: absolute; instead of float: left. In case you want to use float: left with the following structure,
<div class="parent">
<div class="child-left floatLeft"></div>
<div class="child-right floatLeft"></div>
</div>
Give position: auto; to the parent so that it will contain its children height.
.parent {
position: auto;
}
.floatLeft {
float: left
}
I learned of this neat trick in an internship interview. The original question is how do you ensure the height of each top component in three columns have the same height that shows all the content available. Basically create a child component that is invisible that renders the maximum possible height.
<div class="parent">
<div class="assert-height invisible">
<!-- content -->
</div>
<div class="shown">
<!-- content -->
</div>
</div>