I have two div's, wrapped inside one container div. The bottom div contains a dynamically filled table (with variable width), which determines the overall width of all div's.
In the top div, I want to list several small red blocks (div's or span's or whatever). These red blocks need to take the available horizontal space, but wrap to a new line if they reach the max allowed width.
So this is what I want to achieve:
Unfortunately, I can't make it work. No matter how I CSS the red blocks (small floating div's, or inline-block's), they keep on taking more width than allowed. As a result, all div's become a lot wider than allowed, wider than my table:
How can I force these red blocks to only use the allowed with, and pick a new line if they run out of space?
Thanks!
UPDATE:
Here's a working example that shows the red blocks (which have variable length) next to each other, taking up more width than they are allowed. They need to start on a new line as soon as the table's width is reached.
http://codepen.io/anon/pen/bqobGp?editors=1100#0
table td{
border:thin solid gray;
line-height:25px;
padding:0 5px;
}
.div1, .div2 {
margin-top:15px;
padding:20px;
background:white;
box-shadow:2px 0 3px rgba(0,0,0,.12)
}
.container {
display:inline-block;
background:#f1f1f1;
padding:30px;
}
.badge {
line-height:30px;
background:red;
min-width:150px;
color:white;
margin:5px 10px;
text-align:center;
font-family:sans-serif;
border-radius:5px;
display: inline-block;
}
Based on my historical experience, you can achieve such behavior using basic HTML tables if you set small width on a parent table element...
So: for your code, we can use display: table and a small width on .container and white-space: nowrap; for .div2 (to prevent line breaks on table) as following:
.container {
display: table;
width: 50px; /* use a small value */
...
}
.div2 {
white-space: nowrap;
}
here is the updated code pen
/* shrink 2nd div to fit the table */
.div2 {width: fit-content;}
/* shrink first div to minimum size
* but constrain it to shrink no further than width established by its siblings
*/
.div1 {min-width: available; width: min-content;}
alternative approach
.container {width: min-content;}
These width values are fairly new and the spec are still in flux, so different browsers may support them under different names or prefixes may be needed.
I'm not sure what you call your "red" blocks in your css file, but something that is short and simple would be to calculate the width.
For example:
.parent {
width: 100%;
padding: 0;
margin: 0;
background: green;
float: left;
}
.red_block {
width: calc(100% / 5 - 20px); /* Calculate width here - where it takes the full 100% of the parent and divides it by 5 "red blocks" and subtracts 20px for each */
height: 40px;
padding: 0;
margin: 10px;
background: red;
float: left;
}
<div class="parent">
<div class="red_block"></div>
<div class="red_block"></div>
<div class="red_block"></div>
<div class="red_block"></div>
<div class="red_block"></div>
<!-- Will wrap to second line -->
<div class="red_block"></div>
<div class="red_block"></div>
<div class="red_block"></div>
</div>
DEMO
Does this answer your question?
UPDATE:
With your "red blocks" being calculated via width, you can even specify that class in some media queries to change the width to your liking for mobile devices! Example:
#media screen and (max-width: 48em) {
.red_block {
width: calc(100% / 3); /* or to whatever you want...IE: width: 100%; */
}
}
Related
Let say I have a layout with 3 columns:
| left sidebar | content | right sidebar |
Each column is a div with float: left.
I'd like to have the content div always centered, but also set a max-width to it:
| left sidebar | centered + max width | right sidebar |
The total width of the 3 columns should always be 100%, so the two sidebars would have adapt and fill the remaining space.
So in a very big screen it would look like this:
| left sidebar | content | right sidebar |
As if the content div had margin: 0 auto (but with the two divs at the sides instead of empty space).
Is it possible to do such a thing with CSS?
Using flexbox is quite a simple
*{margin:0; box-sizing:border-box;} html,body{height:100%;font:14px/1.4 sans-serif;}
div{ border: 1px solid #000;}
/* here you go */
.flex{ display: flex; }
.grow-1{ flex: 1; }
<div class="flex">
<div>left sidebar</div>
<div class="grow-1">content</div>
<div>right sidebar</div>
</div>
adding the class grow-1 to other elements:
*{margin:0; box-sizing:border-box;} html,body{height:100%;font:14px/1.4 sans-serif;}
div{ border: 1px solid #000;}
/* here you go */
.flex{ display: flex; }
.grow-1{ flex: 1; }
<div class="flex">
<div class="grow-1">left sidebar</div>
<div class="grow-1">content</div>
<div class="grow-1">right sidebar</div>
</div>
Things have changed since float: left was the only solution.
A simpler alternative is to use display properties. An example would be something like this:
div#wrapper {
display: table;
width: 100%;
table-layout: fixed;
}
div#left-sidebar,
div#content,
div#right-sidebar {
display: table-cell;
}
The table-cell property allows the divs to behave like cells in a table without actually using a table — the best of both worlds.
The properties in the wrapper div allow you to specify the width and affect how the cells are distributed.
A better solution would be to use flex-box. However, that only works in modern browsers, so you might have to hold off till you can be sure that there’s no IE lurking about. It’s also a bit harder to learn, but much more flexible.
If you wanted to avoid the use flex-box due to some older browsers not supporting it...
You could use display table properties in the css. A #media query can then be utilized to effectively set the max-width of your content div (i.e. the middle column).
Example media query:
#media (min-width: 300px) {
.middle {
width: 100px !important;
}
}
Note regarding the media query: The width value for the .middle class should equal the #media queries min-width value divided by three. The width value within this context then behaves similar to max-width.
For example; if you want the max-width of the middle column to be 300px, then you set the min-width value for the #media query to 900px. Given this configuration the width of the middle column would remain flexible until the browser width exceeds 900px wide, at which point the middle column width is fixed at 300px wide.
Code snippet:
Here is the full code snippet, including both html and css:
body, html {
padding: 0;
margin: 0;
}
.wrapper {
width: 100%;
height: 100px;
display: table;
background: #BADA55;
table-layout: fixed;
}
.wrapper > div {
display: table-cell;
width: 100%;
text-align: center;
vertical-align: middle;
}
.middle {
background: #C0FFEE;
}
#media (min-width: 750px) {
/*
* The 'width' value below should be the #media
* queries 'min-width' value (above) divided by three.
*
* The 'width' value below is then behaves similar
* to 'max-width'.
*/
.middle {
width: 250px !important;
}
}
<body>
<div class="wrapper">
<div>left sidebar</div>
<div class="middle">content</div>
<div>right sidebar</div>
</div>
</body>
I am developing Facebook application (I am not CSS pro.). The iframe canvas is liquid eg. width 100%.
The main div that hold the application is 500 px wide. There are two divs of left and right from main dic (see picture below). Left and right divs must have the same width.
When user resize browser window I want keep main div centered with fixed width while both left and right divs must resize appropriately to take only available space.
In case there is no space for left and right divs they must disappear. Main div must be centered.
Thank you very much for you help.
</style>
body{
margin: 0px;
padding: 0px;
}
#main{
width: 300px;
display: inline-block;
background: red;
}
#left, #right{
width: calc(50% - 150px);
display: inline-block;
background: green;
}
#media (max-width: 400px) {
#left, #right{
display: none;
}
}
</style>
<body>
<div style="text-align: center;">
<div id="left">1</div><div id="main">2</div><div id="right">3</div>
</div>
</body>
This is what I have so far: http://jsfiddle.net/clicker314/L77jh8ak/4/
If you are willing to use the calc() CSS function, this problem is relatively easy to solve:
#main{
width: 500px;
display: inline-block;
}
#left, #right{
width: calc(50% - 250px);
display: inline-block;
}
Thus, the left and right divs adjust their height based on the width of half of the screen, minus half of the main element. If you want a fallback, add another 'width:' rule on the line prior to the calc() width rule.
This works on all modern browsers, including IE 10+. If you want IE 8/9 support, add the second width rule I mentioned above.
For IE 8/9 support, you have two options:
1. Give a defined width for those two options. I.e. #left, #right{width: 200px;}.
2. Add some JS/jQuery to imitate the CSS calc() function.
To hide the divs on a certain size, add a media query (the 600px I added is hypothetical, pick any minimum screen size you like):
#media (max-width: 600px) {
#left, #right{
display: none;
}
#main{
width: 100%;
}
}
The #main rule there is optional. It assumes that you want the #main div to take up all of the space available in the container.
I would like to create a div (within a main wrapper for a website) to contain 2 div to fill in the previously mentioned div. I have actually done this already....but my problem is that the 2 smaller divs dont align nor stay fixed in the main div. How is this even possible if they are confined to a main div?
Here is what I have done so far and there this issue is present: http://jsbin.com/tifuhute/17/
The text and the map (both with black borders) should be in the red box (which is the main div) and shouldnt move under no circumstances.
The sizing is a little off. (#column1 (300px) + #column2 (900px) = 1200px not 1198). Use box-sizing:border-box; to make it easier
#container {
width:1200px;
...
}
#column1 {
width:300px;
box-sizing:border-box;
...
}
#column2 {
width:900px;
box-sizing:border-box;
...
}
http://jsbin.com/tifuhute/18/
Your divs have fixed width and height. Your container is 1198px wide, while your inner divs sum up 1200px, thus wrapping as they don't fit in their parent's 1198px width.
Give both your divs "display: inline-block". This will make them line up side by side as long as their width is not greater than that of the red box.
#text{
display: inline-block;
width: 30%;
#map{
display:inline-block;
width: 69%;
}
You will want to float the inner divs.
Because div elements display as block they won't follow each other horizontally in-line. Using float will put them next to one another.
Don't forget to account for the border width of each inner element so they fit inside the wrapper. In the below example the larger div has a width of 646px instead of 650px because 4px were used for the right and left border of the inner div's combined.
<div id="wrapper">
<div id="small-div"></div>
<div id="large-div"></div>
</div>
#wrapper{
width: 900px;
height: 300px;
padding: 0;
margin: 0;
border: 1px solid red;
}
#small-div, #large-div{
float: left;
border: 1px solid #000;
}
#small-div{
width: 250px;
height: 300px;
}
#large-div{
width: 646px;
height: 300px;
}
JSFiddle example
I actually don't know how to name my question. But I will explain what I need to do.
HTML is simple as this:
<div id="left_div"></div>
<div id="right_div"></div>
I need left_div to be on the left, to have 100% width, but with fixed right margin 320px. right_div has fixed width 300px and must be alongside left_div.
I know I can do this very easily, when I would do this:
<div id="right_div" style="float:right;width:300px"></div>
<div id="left_div" style="margin-right:320px;"></div>
But the problem is that I need HTML to be as I mentioned before. The order of DIVs matter. If someone wonders why, it's because I am working on responsive website, where I need, when the viewport is too narrow, the right_div to be below left_div. And that I can't do with simple solution I have put above.
I hope my question makes sense and I am thankful for any answers or helpful hints.
Oh, and I forgot to mention I need this to be pure HTML+CSS, no JS. And I don't need to support IE7 and below.
UPDATE:
left_div must be width:auto and right margin must be fixed (e.g. 300px).
If you want your layout to be responsive you should use a CSS framework like Columnal, 1140, or more in this list.
Most of these frameworks supports the grid system, which is the best way to structure your layout and you don't have to worry about floats and pixels anymore.
I think that what do you want is almost impossible with just pure HTML + CSS.
What may work for you is something like this one I did: http://jsfiddle.net/fmZAm/
HTML:
<div class="main">
<div class="left"></div>
<div class="right">
<div class="fixed_content"></div>
</div>
</div>
CSS:
div.main
{
min-height: 500px; /* force some height */
min-width: 300px; /* min width to show content */
text-align: center; /* center content when in vertical responsive mode */
font-size: 0px; /* remove blank space from 'inline-block' display */
}
div.main > div /* left and right divs */
{
width: 100%; /* force both to have as max width as possible */
min-height: inherit; /* same min height as parent */
min-width: inherit; /* same min width as parent to show content */
display: inline-block;
}
div.left
{
max-width: 58%; /* 100% width from max of 58% parent width */
background-color: lightgreen;
}
div.right
{
max-width: 42%; /* 100% width from max of 42% parent width */
text-align: right; /* put child 'inline-block' divs to the right */
background-color: dodgerblue;
}
div.right > div.fixed_content
{
width: 300px; /* set the 300px right div you want */
min-height: inherit; /* same min height as parent */
background: orange;
display: inline-block;
}
As both divs (left and right) will have % widths, both will resize based on the current max width, but you'll have your fixed width div inside of the right div. So, when your right div resize to 300px width (the fixed with of its child div) it will go below the left div.
Hope it helps!
I had the same issue, I solved it using position:absolute.
HTML
<div class="container">
<div id="left_div"></div>
<div id="right_div"></div>
</div>
CSS
.container {
position:relative;
}
#left_div {
float: left;
width: auto;
margin-right: 320px;
}
#right_div {
position:absolute;
top:0;
right:0;
width: 300px;
}
Here's the sample/jsFiddle: http://jsfiddle.net/antonpug/ub7xW/
Basically, you can't see it in the jsFiddle, I don't think, but it is two columns when it is full screen, however, when you make the screen smaller, it collapses down to just one column - I can't figure out where in my CSS it is doing that!
This causes it:
.column {
display: inline-block;
width:600px;
margin:15px;
}
The inline-block will cause them to sit next to each other if your wrapper is 1200px or more, but otherwise it won't. Set a min-width if you don't want it to wrap.
#wrapper {
min-width: 1200px; /*might need a bit more for margins*/
margin:25px;
}
If you do want the columns next to each other you must specify a width under your body selector.
Something like
body {width:1500px;}
This forces the body to overflow the screen and place the columns next to each other. Otherwise, the width of the screen (or "viewing area") sets the width for the body selector because it's default is width:auto.
change css to
#wrapper {
margin: 25px auto;
width: 80%;
}
and
.column {
display: inline-block;
width: 46%;
margin: 15px;
float: left;
}
It's pretty straight forward:
.column {
display: inline-block;
width:600px;
margin:15px;
}
You have 2 DIVs both with ".column". These DIVs have a static width of 600px. They will float next to each other as long as there's space for them (ie. 1200px container)
They collapse because the page is too small for them.
If you're looking to keep 2-columns, you need to set the width to a % like so:
.column{
...
width: 40%;
}
you will have to do some adjustments for your margins as well, depending on what you're looking for.
If you want to keep 2 columns until a certain size, you can set a min-width on your wrapper element so you columns won't get too small:
.wrapper{
min-width:600px;
}
You can then run a media query for smaller screen sizes so you can collapse your columns into one for things like mobile phones.
change the column's css to this and it should be fine.
.column {
display: inline-block;
margin:15px;
width:40%;
}