CSS scale divs in float layout - html

I want to create an automatic scaling layout without using the height property. I use a float layout between two divs, as shown in the image. The boxes in the middle have content of different size and I want the boxes to scale in such way, that all have the same height.

Try reading this article at css-tricks.
My favorite choice is probably the one taken from Paul Irish's blog at HTML5Rocks - however it does rely on modern browsers. I've created a JSFiddle based on his code:
CSS
.box {
/* basic styling */
width: 100%;
height: 95px;
border: 1px solid #555;
font: 14px Arial;
/* flexbox setup */
display: -webkit-box;
-webkit-box-orient: horizontal;
display: -moz-box;
-moz-box-orient: horizontal;
display: box;
box-orient: horizontal;
}
.box > div {
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
}
/* our colors */
.box > div:nth-child(1){ background : #FCC; }
.box > div:nth-child(2){ background : #CFC; }
.box > div:nth-child(3){ background : #CCF; }
HTML
<div class="box">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
However note this won't work with legacy browsers, and if you're targeting those, I suggest you just adopt a table layout.

I have made a JsFiddle.
What I basically do, is use the position:absolute in combination with the top and bottom CSS property to force the inner div to take full height.
HTML:
<div id="top"></div>
<div id="middle"></div>
<div id="bottom"></div>
CSS:
body{
margin: 0px;
padding: 0px;
border: 0px;
}
#top{
width: 100%;
height: 30px;
background: blue;
position: absolute;
}
#bottom{
width: 100%;
height: 30px;
background: yellow;
position: absolute;
bottom: 0px;
}
#middle{
width: 30%;
position: absolute;
top: 30px;
bottom: 30px;
background: gray;
}

place the middle one in a div
and make the three divs inside it and give them height 100%

Use min-height. Examples of this property are provided below.
MDN
MSDN

Related

CSS Flex stretching out links

So I am learning a bit more about using CSS flex instead of using static positioning of content. However, I have defined my link styles as well as bold styles. My guess is that it's adapting to the container that is in (which is using flex feature) and that is why it is stretching across the size of the container it is inside. My question now is, how do I fix this? I've seen that I can do "display:inline-block" on the link, but that has not fixed it.
Here is my code:
.container{
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
width: 80%;
margin: auto;
background-color:#fff;
overflow: hidden;
font-size: 15px;
line-height: 20px;
padding:1em;
}
.container > * {
padding: 15px;
-webkit-flex: 1 100%;
flex: 1 100%;
}
a{
text-decoration:none;
border-bottom-style:double;
border-bottom-width:2px;
color:#99d3df;
display:inline-block;
padding:0px;
overflow: hidden;
}
i{
display:inline-block;
color:#88bbd6;
text-decoration:italic;
}
And what I have:
This is a Google Link<BR>
Google is <i>extremely helpful</i>!
This is what it looks like for reference.
Problem image
It seems you missed the .container wrapper div in the markup you provided.
Let's look at this code:
<!-- HTML -->
<div class="container">
<span>This is a </span><a href="http://google.com">Google Link</a
</div>
<div class="container">
<span>Google is </span><i>extremely helpful</i>!
</div>
<!-- /HTML -->
/* CSS */
.container > * {
padding: 15px;
-webkit-flex: 1 100%;
flex: 1 100%;
}
Property flex with value of 1 100% means we tell the browser to style any elements (the asterisk *) nested in .container to have 100% width of their parent's width.
I would suggest you to just remove that part to fix the problem.
Here's my approach to your markup.
.container {
display: flex;
width: 80%; /* flexible value */
flex-direction: row; /* this is to make sure that we'll have side-to-side layout within .container */
}
a {
text-decoration: none;
border-bottom-style: double;
border-bottom-width: 2px;
color: #99d3df;
display: inline-block;
padding: 0px;
}
a, i{
margin-left: 5px; /* this is to give a 10px spacing */
}
<div class="container"><span>This is a </span>random link<span></span></div>
<div class="container"><span>Google </span><i>is extremely helpful! </i></div>
It is working fine when I tried your code in js fiddle
see in this image
May be some other css is affecting your links to stretch it out.

How do I make a responsive div with scroll content in HTML?

I have the following code:
/* css */
.phone {
height: 100%;
width: 40%;
overflow: hidden;
padding: 0;
border-radius: 3%;
border: 2px solid red;
}
.phone .screen {
height: 50%;
overflow-y: auto;
background-color: #c3cee0;
}
.phone .nav {
background-color: black;
overflow: hidden;
color: white;
}
<!-- HTML -->
<div class="phone">
<div class="screen">
<p>Lorem Ipsum...</p>
...
<p>Lorem Ipsum...</p>
</div>
<div class="nav">
<p>Back</p>
<p>Home</p>
<p>Menu</p>
</div>
</div>
I want the phone to be responsive but in order to enable the scroll in the div.screen I need to set the height of the div.phone. The problem is that the red border is going beyond the phone's content.
I'd like the border to finish where the div.nav ends but I'm getting unwanted extra space. See this live demostration.
TL;DR
Live demostration.
I need to set a height (for div.phone) in order to enable the scroll for the text messages but then I get that extra space shown by the red border. How can I make div.phone (red border) be the same height of the whole content (without the extra space)?
Set height using calc().
.phone .screen{
height: calc(100% - 33px);
}
33px is the height of bottom nav.
Here is solution you need to remove height:100% prperty from .phone and define height in px in .phone .screen so it will work fine
Here is updated css
.phone {
height:auto;
}
.phone .screen {
height: 400px;
overflow-y: auto;
background-color: #c3cee0;
}
And here is live demo
I fixed the issue by using display: flex. Live demonstration.
Basically
.phone {
height: 50%; /* whatever height you need */
display: flex;
flex-direction: column; /* used to separate the divs vertically */
/* instead of horizontally */
border-radius: 3%;
border: 2px solid red;
}
.phone .screen {
flex: 9; /* screen will take 9/10 spaces from the div.phone */
overflow-y: auto; /* enables scroll */
}
.phone .nav {
flex: 1; /* nav will take 1/10 spaces from the div.phone */
}

Swap div order using css only

I am wondering if it's possible to display two div elements in inverted order using only css.
No html change or javascript code, just css.
I have the following html:
<div id="container" class="clearfix">
<div id="right-sidebar">Right</div>
<div id="left-sidebar">Left</div>
</div>
and this current css:
#container {
width: 200px;
border: 2px solid blue;
padding: 2px;
margin: 0;
}
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
#left-sidebar, #right-sidebar {
width: 150px;
padding: 2px;
}
#left-sidebar {
border: 2px solid red;
float: left;
}
#right-sidebar {
border: 2px solid green;
float: right;
}
The result shows the right div above the left one. I'd like to swap them, showing the left one above the right one, maintaining the container properties (auto calculated height).
To explain it in different words, I'd like to achive using just CSS the same result I would obtain by swapping the two divs in the html code.
Is it even possible with only css? [I'm dreaming about a float: bottom property :)]
http://jsfiddle.net/mT7JJ/1/
According to this and many others, i am afraid you can not swap only with css, but I've found something that will help you in this situation and that is this
So this will be your edit on fiddle
#container {
display: table; width: 200px;
border:1px red solid;
}
#left-sidebar {
display: table-header-group;
}
#right-sidebar {
display: table-footer-group;
}
The only think i can think about is relative/absolute position. But it will not be really efficient though
One modern solution, as has been comented, is flex layout.
Another tricky posibilitity is using transforms
webkit demo
I an just rotating the container upside down, and then rotaing the inner divs to make them look ok. It's done in the hover, to show the net effect.
The hover is a little bit inestable due to the clearfix, but this is not relevant here.
#container:hover {
-webkit-transform: rotateX(180deg);
}
#container:hover div {
-webkit-transform: rotateX(180deg);
}
I enjoy answering a question that has been declared imposible :-)
<div id="container" class="clearfix">
<div id="left-sidebar">Left</div>
<div id="right-sidebar">Right</div>
</div>
#container {
width: 200px;
border: 2px solid blue;
padding: 2px;
margin: 0;
}
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
#left-sidebar, #right-sidebar {
width: 150px;
padding: 2px;
}
#left-sidebar {
border: 2px solid red;
}
#right-sidebar {
border: 2px solid green;
}
check this left div above right div
Using CSS only:
#blockContainer {
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: vertical;
-moz-box-orient: vertical;
box-orient: vertical;
}
#blockA {
-webkit-box-ordinal-group: 2;
-moz-box-ordinal-group: 2;
box-ordinal-group: 2;
}
#blockB {
-webkit-box-ordinal-group: 3;
-moz-box-ordinal-group: 3;
box-ordinal-group: 3;
}
<div id="blockContainer">
<div id="blockA">Block A</div>
<div id="blockB">Block B</div>
<div id="blockC">Block C</div>
</div>
http://jsfiddle.net/hLUHL/713/
no expert and old question but use case apply for me under specific conditions to anwser this question: "Swap div order using css only"
My answer is almost entirely based on Harry's answer here https://stackoverflow.com/a/31366853/3913379 (Original Answer v2) and tested nowadays (Chrome/FF) under the condition that the child divs are same size (use case is main Div contains TWO divs with link icons and text).
So to swap TWO divs left to right and vice versa using CSS only I used a css transform on X axis (transform: translateX ), like this:
<STYLE type="text/css">
#Child1Div {transform: translateX(100%);}
#Child2Div {transform: translateX(-100%);}
</STYLE>
<div id="MotherDiv" >
<div id="Child1Div">Context of child one</div>
<div id="Child2Div">Content of child two</div>
</div>
So, note usage of percentages and negative values in one case, to attain basically "the swap". HTML structure is unchanged (and JS/JQuery listeners were unaffected, for example link's onClick(...) )
This may fail under some inherited special styles but simple case worked nicely for me.
Style can be applied in HEAD tag or inline on divs or also dynamically via JS (for example to swap two Icons/Images via a button click or something like that)
There are two ways to do that with css. Flex and Grid.
Flex:
#container {
display: flex;
flex-wrap: wrap;
position: relative;
justify-content: flex-start;
flex-direction: row-reverse;
}
Grid:
#container {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr))
}
#left-sidebar {
order 2
}
#right-sidebar {
order 1
}

CSS Table Styles - Get table row to fill entire content area

I'm trying to use the CSS table display to layout my page and I'm having trouble getting my main content area to take up the entire area (vertically) between the header and the footer. The main div contains some floated elements that don't necessarily extend the length of the screen. Basically, no matter what I do, the area of my main content is decided by the vertical height of these elements. Is there anything I can do about this? Thanks!
Html:
<div id="all-container">
<div id="header">
...
</div>
<div id="table-container">
<div id="content">
<div id="side-bar">
...
</div>
<div id="main">
... some content that's floated ...
</div>
</div>
</div>
<div id="footer"></div>
</div>
CSS:
#all-container {
margin:0px;
position:relative;
min-height:100%;
background-color:#E6DCD8;
}
#header {
height:60px;
padding-left:20px;
padding-right:20px;
background-color:#685642;
}
#table-container {
display:table;
height:100%;
}
#content {
display:table-row;
height:100%;
}
#side-bar {
display:table-cell;
vertical-align:top;
padding-right:100px;
height:100%;
padding-bottom:60px;
}
#main {
display:table-cell;
vertical-align:top;
border-left-style:solid;
border-left-width:normal;
border-left-color:#685642;
padding-bottom:60px;
height:100%;
}
#footer {
position:absolute;
width:100%;
height:50px;
bottom:0px;
background-color:#685642;
}
I'm going to take a shot in the dark at trying to answer. These are my suggestions, not necessarily the canonical correct answer you're looking for.
Not answering exactly to the question on table layout per say, but I'm offering other ways to achieve the same desired result.
This is your original code in the fiddle http://jsfiddle.net/CRzfS/
I think you have at least two design objectives here you want to achieve:
make a full screen height layout
make a 2-column layout
I'll have to put it forward first, that there are many ways to achieve the objective, but all has their limitations due to browser support. I also advise against table layouts unless it is necessary.
For me, display: table is only used for one reason mostly: Making vertical-align work in a fixed-height container, especially vertical-align: middle. There are also relevant uses for the auto calculation of table-cell widths from a fixed-width table, but it all depends on how you want to present data or information.
We'll face the issues one by one.
Full Height
First is the layout's height issue. Height flexibility has always been a sore point in web design layouts.
To fill screen height only, you can look at this sticker footer implementation:
http://www.cssstickyfooter.com/
Here's an example fiddle with full screen height, not taking footer implementation into account: http://jsfiddle.net/CRzfS/3/
CSS:
html, body {
height: 100%;
min-height: 100%;
}
For liquid height layout you can look at this: http://www.mightymeta.co.uk/superstretch-a-vertically-fluid-layout-using-css/
For a proper flexible height, you'll have to use CSS Flexbox.
http://caniuse.com/#feat=flexbox
You can try it out here http://flexiejs.com/playground/
Your example implemented using CSS Flexbox: http://jsfiddle.net/CRzfS/4/
CSS:
html, body {
height: 100%;
min-height: 100%;
margin: 0;
padding: 0;
}
#all-container {
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: vertical;
-moz-box-orient: vertical;
box-orient: vertical;
margin:0px;
position:relative;
min-height:100%;
height: 100%;
background-color:#E6DCD8;
}
#header {
height:60px;
padding-left:20px;
padding-right:20px;
background-color:#685642;
}
#table-container {
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
-webkit-box-orient: vertical;
-moz-box-orient: vertical;
box-orient: vertical;
}
#content {
display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
overflow: hidden;
}
#side-bar {
vertical-align:top;
min-width: 150px;
}
#main {
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
vertical-align:top;
border-left-style:solid;
border-left-width:normal;
border-left-color:#685642;
}
#footer {
width:100%;
height:50px;
background-color:#685642;
}
Two-column Layout
There are many ways to achieve this. Considerations have to be made for the differing screen sizes you're supporting(which is a major headache). Each has their own drawbacks. And also it depends on your width requirements i.e. fixed width, flexible width.
semantic way by absolute positioning the sidebar and setting margin for main content
common method used by layout frameworks via floating sidebar and container so they are side by side
using display: inline-block to the same effect as #2.
The first method here, sets your #side-bar after the #main in the HTML. Then using CSS absolute positioning to set #side-bar to the left side, and setting margin-right for your #main. http://jsfiddle.net/CRzfS/2/
HTML:
<div id="table-container">
<div id="content">
<div id="main">
... some content that's floated ...
</div>
<div id="side-bar">
...
</div>
</div>
</div>
CSS:
#table-container {
position: relative;
}
#content {
height: 200px;
}
#side-bar {
width: 200px;
position: absolute;
left: 0;
top: 0;
background-color: rgba(255,255,255,0.5);
height: 100%;
}
#main {
margin-left: 200px;
height: 100%;
overflow: hidden; // for floated elements within
}
The second method here, using the original HTML, you'll only need to set the CSS. http://jsfiddle.net/CRzfS/5/
#table-container {
overflow: hidden;
}
#content {
width: 100%;
}
#side-bar {
width: 33%;
float:left;
}
#main {
width: 66%;
float: left;
vertical-align:top;
border-left-style:solid;
border-left-width:normal;
border-left-color:#685642;
padding-bottom:60px;
min-height: 100px;
overflow: hidden; // for floated elemnts
}
How to combine these 2 layout requirements together will be difficult if I'm not sure of what you exactly require for the vertical height part.
I'll need more information before I can give a relevant answer tailored to your question.
Resources
If you're open to layout grid systems framework, I'll suggest you take a look at: http://twitter.github.com/bootstrap/scaffolding.html#gridSystem
Even if you don't want to use it, just looking at the CSS implementation will yield you interesting insights.
I'll be adding other jsfiddle examples as more information on the question comes.
Edit: More information and explanations added.

HTML5 flexible box model height calculation

after researching the flexible box model for a whole day, I must say I really like it. It implements the functionality I implement in JavaScript in a fast and clean way. One thing however bugs me:
I can't expand a div to take the full size calculated by the flexible box model!!!
To illustrate it I'll proved an example. In it the two flexible places take the exact with and height, but the div inside it only takes the height of the "<p>...</p>" element. For this example it doesn't matter but what I originally was trying was placing a "flexible box model" inside another "flexible box model" and this must be possible in my opinion
html, body {
font-family: Helvetica, Arial, sans-serif;
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
#box-1 {
background-color: #E8B15B;
}
#box-2 {
background-color: #C1D652;
}
#main {
width: 100%;
height: 100%;
overflow-x: auto;
overflow-y: hidden;
}
.flexbox {
display:-moz-box;
display:-webkit-box;
display: box;
text-align: left;
overflow: auto;
}
H1 {
width: auto;
}
#box-1 {
height: auto;
-moz-box-orient: vertical;
-webkit-box-orient: vertical;
box-orient: vertical;
-moz-box-flex: 3;
-webkit-box-flex: 3;
box-flex: 3;
}
#box-2 {
height: auto;
min-width: 50px;
-moz-box-orient: vertical;
-webkit-box-orient: vertical;
box-orient: vertical;
-moz-box-flex: 1;
-webkit-box-flex: 1;
box-flex: 1;
}
#fullsize{
background-color: red;
height: 100%;
}
<div id="main" class="flexbox">
<div id="box-1" class="flexbox">
<div id="fullsize">
<p>Hallo welt</p>
</div>
</div>
<div id="box-2" class="flexbox">
</div>
</div>
I've been wrestling with this myself, but have finally managed to come up with a solution.
See this jsFiddle, although I have only added webkit prefixes so open in Chrome.
You basically have 2 issues which I will deal with separately.
Getting the child of a flex-item to fill height 100%
Set position:relative; on the parent of the child.
Set position:absolute; on the child.
You can then set width/height as required (100% in my sample).
Fixing the resize scrolling "quirk" in Chrome
Put overflow-y:auto; on the scrollable div.
The scrollable div must have an explicit height specified. My sample already has height 100% but if none is already applied you can specify height:0;
See this answer for more information on the scrolling issue.
You must also make the div you want to expand a flex-box as well and add a flex value.
This fixes the problem.
#fullsize{
background-color: red;
display: -webkit-box;
display: box;
display: -moz-box;
box-flex:1;
-webkit-box-flex:1;
-moz-box-flex:1;
}