Table like layout in responsive design cross browser - html

In a webpage i have following markup for my layout
<div class="parent">
<div class="left-content"></div>
<div class="right-content"></div>
</div>
and the styles for the given markup are:
.parent{
display:table;
width:100%;
}
.parent > .left-content{
width:auto;
}
.parent > .right-content{
width:320px;
}
How do I make the "right-content" occupy 320px of available width and the "left-content" div occupy all the remaining width?
Note that: i can not use the following technique to achieve this behaviour as my layout is responsive and i need to move the "right-content" to the bottom of "left-content" at specific resolution.
Markup:
<div class="parent">
<div class="right-content"></div>
<div class="left-content"></div>
</div>
Styles
.parent{
display:block;
width:100%;
}
.parent > .left-content{
width:auto;
}
.parent > .right-content{
width:320px;
float:right;
}

To make things easier I would first change the markup so you have the left content is below your right-content (as desired on smartphone-resolutions).
<div class="left-content"></div>
<div class="right-content"></div>
Next, because your first div is the one that takes up remaining width, the simple solution seems to be display:table-cell (and the parent as display:table). It looks doable with inline-blocks or floats as well, but you may have to resort to something like width: calc(100% - 320px); so I like the table solution a little bit more.
Next you add a simple media query to change back to blocks on lower resolutions.
.parent {
display: table;
width: 100%;
}
.parent > .left-content {
display: table-cell;
width: auto;
/* Added for visualisation */
background: blue;
height: 50px;
}
.parent > .right-content {
display: table-cell;
width: 320px;
/* Added for visualisation */
height: 50px;
background: red;
}
/* Media query */
#media(max-width: 550px) {
.parent > .left-content {
display: block;
}
.parent > .right-content {
display: block;
width: 100%;
}
}
<div class="parent">
<div class="left-content">Left</div>
<div class="right-content">Right</div>
</div>

I would strongly suggest using calc rather than forcing your markup to behave like a table.
http://sassmeister.com/gist/c87585fcff7fae356adb
.left-content,
.right-content {
width: 100%;
}
#media (min-width: 600px) {
.left-content {
float: left;
width: calc(100% - 320px);
}
.right-content {
float: right;
width: 320px;
}
}

Related

CSS - Make multiple divs in columns wrap back around

Say I have three divs - Red Green and Blue with the following basic markup and styles: https://jsfiddle.net/ar8sn1o6/
<div class="red">Red</div>
<div class="green">Green</div>
<div class="blue">Blue</div>
.red, .green, .blue {
display: inline-block;
float: left;
margin: 1%;
width: 48%;
}
.red {
background: red;
height: 50px;
}
.green {
background: green;
height: 100px;
}
.blue {
background: blue;
height: 50px;
}
But I want to be displayed in two column on desktop and one column on mobile like this. Whilst it is reasonably straight forward to have a Red -> Blue -> Green mobile layout, I need to instead have a Red -> Green -> Blue layout
Is this possible without duplicating any HTML?
It is possible using media queries
Check out this article to find out more: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries
Syntax
Media queries consist of an optional media type and can, as of the
CSS3 specification, contain zero or more expressions, expressed as
media features, which resolve to either true or false. The result of
the query is true if the media type specified in the media query
matches the type of device the document is being displayed on and all
expressions in the media query are true.
See snippet below. Resize it to see it working!
.red, .green, .blue {
display: inline-block;
float: left;
margin: 1%;
width: 48%;
}
.red {
background: red;
height: 50px;
}
.green {
background: green;
height: 100px;
}
.blue {
background: blue;
height: 50px;
}
#media (max-width: 400px) {
.red, .green, .blue {
display: block;
width: 100%;
}
}
<div class="red">Red</div>
<div class="green">Green</div>
<div class="blue">Blue</div>
UPDATE
What you're trying to achieve is not possible with CSS only.
Ill try to explain why not.
When you style elements with float: left or display: inline-block. They have an parent element which has the height of the highest child. So every new block thats inserted on a new row will allign at the bottom of the highest previous child.
So aligning them as you want is not possible. However, you can wrap an div around it. And then just add float: left; or display: inline-block. See this example: https://jsfiddle.net/ar8sn1o6/2/
NOTE:
When using float, the parent element will lose its height. You can fix this by adding overflow: hidden to the parent element.
Or use clearfix. See: https://css-tricks.com/snippets/css/clear-fix/
You could use Media queries to specify certain CSS when the viewport of the device is smaller than a certain/specified size.
For example:
#media screen and (max-width: 480px) {
container {
width: 100%;
}
.blue {
background-color: blue;
width: 90%;
height: 50px;
}
}
This would mean that if the width of the device was smaller than 480px, these styles would take effect. I think if you put them all in a container and they all had a width of say 90%, they would align one by one below each other in the mobile view.
Hope that helps
Put a container and add media-query
.red, .green, .blue {
display: inline-block;
margin: 1%;
}
.red {
background: red;
height: 50px;
width:100%;
}
.green {
background: green;
height: 100px;
}
.blue {
background: blue;
height: 50px;
width:100%;
}
.container, .green{
float:left;
width: 48%;
}
#media only screen
and (max-width: 480px) {
.container, .green{
width: 100%;
}
}
<div class="container">
<div class="red">Red</div>
<div class="blue">Blue</div>
</div>
<div class="green">Green</div>

2 columns, one side fluid , one side fixed

Ok, so i thought this was easy as 123. I've research here and tried a couple of solutions. For some reason, i can't get it right.
Basically, i'm trying to do a layout where the left column is fluid and the right column is fixed.
HTML:
<div class="column-ab">
<div class="col-content">content section</div>
<div class="col-aside">side section</div>
</div>
CSS:
.column-ab {background-color: black; width: 100%;}
.column-ab .col-aside, .column-ab .col-content {float: left;}
.column-ab .col-content {background-color: cyan; margin-right: 300px;}
.column-ab .col-aside {background-color: yellow; width: 300px;}
.column-ab:after {display: table; content: ""; clear: both;} /* clear */
jsfiddle:
https://jsfiddle.net/ud1frxdp/
Why something so easy doesn't work?
Turn your classes into ids or they will both inherit a width of 100%; then set the width.
.column-ab {background-color: black; width: 100%;}
#col-aside, #col-content {float: left;}
#col-content {background-color: cyan; width: calc(100% - 300px);}
#col-aside {background-color: yellow; width: 300px;}
.column-ab:after {display: table; content: ""; clear: both;} /* clear */
<div class="column-ab">
<div id="col-content">content section</div>
<div id="col-aside">side section</div>
</div>
As an alternative solution your problem can also be solved using few lines of flexbox layout. Code explanation in comments.
.column-ab {
display: flex;
flex-wrap: wrap; /* Wrap the divs when width is too small i.e. <300px of viewport */
}
.col-content {
flex: 1; /* Expands and shrinks according to width, fluid content */
background: tomato;
}
.col-aside {
flex: 0 0 300px; /* flex-basis: 300px for fixed width */
background: lightblue;
}
<div class="column-ab">
<div class="col-content">content section</div>
<div class="col-aside">side section</div>
</div>
Updated JSfiddle
Using display: table; and display: table-cell; is a common use and also a wide cross-browser code, compatibility from IE8 http://caniuse.com/#search=table
https://jsfiddle.net/ud1frxdp/3/
.column-ab {
background-color: black;
width: 100%;
display: table;
}
.column-ab .col-aside, .column-ab .col-content {
display: table-cell;
}
.column-ab .col-content {
background-color: cyan;
}
.column-ab .col-aside {
background-color: yellow;
width: 300px;
}
I also exploded your CSS because of readability, you should avoid coding like this and use a post-processor to minify it, being able to read the code is very important.

Make container div clear when its content can't fit in one line?

I have a liquid layout. When the layout is wide enough some divs (.one and .two) can all line up horizontally on one line.
When the layout is squeezed eventually the right floated divs (.two) end up on multiple lines. Is there a way (without width based media queries) to make the left floated divs clear onto their own line when they cant all fit in a line. I assume I would need to be clear .cont2.
Below is my code an images of what im trying to achieve.
http://codepen.io/anon/pen/JcDlh
<div class="cont">
<div class="one">
</div>
<div class="cont2">
<div class="two"></div>
<div class="two"></div>
<div class="two"></div>
</div>
</div>
.cont {
background: blue;
width: 40%;
margin: auto;
overflow: auto;
}
.one {
background: red;
height: 100px;
width: 300px;
float: left;
}
.two {
float: right;
border: 1px solid black;
height: 100px;
width: 100px;
background: white
}
You could try:
.cont2 {
float: left;
overflow: auto;
}
See example at: http://codepen.io/anon/pen/kczux
to make them all together go to the next line (instead of one by one) you could use a float on the cont2 element. But for making it float to the left instead to the right, I think you need media queries.
http://codepen.io/anon/pen/Jbjmp
Just add to your CSS: .cont2 { float: right; }
It will make your cont2 div stick to the right with all of his child divs, and when you resize screen it will go to new line. For lower resolutions you will need media queries
You can use media queries for this, this is my take:
http://jsfiddle.net/S4R6h/
You can read a little here about how to target various devices based on size: http://css-tricks.com/snippets/css/media-queries-for-standard-devices/
Make the fiddle window very wide and you'll see what you've got when your code sits nicely in a line. Then shrink the window and the media query kicks in and for the purposes of showing you, the body will go black.
HTML:
<div class="cont">
<div class="one">
</div>
<div class="cont2">
<div class="two"></div>
<div class="two"></div>
<div class="two"></div>
</div>
</div>
CSS:
.cont {
background: blue;
width: 40%;
margin: auto;
overflow: auto;
}
.one {
background: red;
height: 100px;
width: 300px;
float: left;
}
.two {
float: right;
border: 1px solid black;
height: 100px;
width: 100px;
background: white
}
#media only screen
and (max-width : 1530px) {
/* Styles */
/* when the query kicks in we decend into night */
body{
background: #000;
}
.one {
background: red;
width: 100%;
}
.two{
width: 33.333%;
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
}
With media queries this would be quite easy, I recommend checking those out. But if you're not willing to use them you could do the following:
Add display:inline-block to .cont2
.cont2 {
display: inline-block;
}
And remove the float:left from .one and instead of it add there display: inline-block; too. So .one would look like
.one {
background: red;
height: 100px;
width: 300px;
display:inline-block;
}
That way the .cont2 div will align to the left when there's not enought space for it to be on the same line with .one .
Here's a codepen: http://codepen.io/anon/pen/qLljt

DIVs Arrangement - HTML CSS

How can i construct above arrangement without using js ?
Thanks in advance !
#div3 {
display: inline-block;
}
#div1 {
min-width: 150px;
float: left;
}
#div2 {
max-width: 100%;
float: left;
}
http://jsfiddle.net/XCDsu/4/ - how can i fit the second div to content ? The first one has to be 150px not percent
all of those techniques in the other answers have a common problem.
they are assuming that the width of the first column is 150px, but actually you need min-width to be 150px. so what happens when the first column need to grow?
take a look at my solution. pure CSS, without using calc (so its also supported in older browsers like IE8)
Working Fiddle
HTML: nothing new here..
<div id="Container">
<div id="Column1">content</div>
<div id="Column2">content of second div is very very large</div>
</div>
CSS:
#Container
{
width: 80%; /*Change to WTE you want*/
display: table;
border: 1px solid black;
margin: 0 auto;
}
#Container > div
{
display: table-cell;
}
#Column1
{
background-color: red;
min-width: 150px; /*From your CSS*/
}
#Column2
{
background-color: green;
}
You could use the holy grail technique:
http://alistapart.com/article/holygrail
#div3 {
display: block;
background: blue;
padding-left: 150px;
}
#div1 {
width: 150px;
float: left;
margin-left: -150px;
}
#div2 {
width: 100%;
float: left;
}
What this does is create a 150px wide padding on the left of #div3, but it pulls #div1 into it with the negative margin.
This way the "100%" that #div2 uses is actually (100% - 150px) of #div3
If the width of #div1 is fixed at 150px and #div3 is dynamic, then you can use :
#div2 {
width : calc(100% - 150px);
}
And if #div1 is also dynamic, then you need to use JS.

Make floating divs the same height

I have 2 divs side by side. I don't know the height of them upfront, it changed according to the content. Is there a way to make sure they will always be the same height, even when one of them stretches, only with CSS?
I made a fiddle to show. I want the red and blue divs to be the same height...
http://jsfiddle.net/7RVh4/
this is the css:
#wrapper {
width: 300px;
}
#left {
width:50px;
background: blue;
float:left;
height: 100%; /* sadly, this doesn't work... */
}
#right {
width:250px;
background: red;
float:left;
}
You could try instead of using float, use display: table-cell. You might find some older browsers don't understand this rule however. See below:
#wrapper {
display: table; // See FelipeAls comment below
width: 300px;
}
#left {
display: table-cell;
width: 50px;
background: blue;
}
#right {
display: table-cell;
width: 250px;
background: red;
}
Antony answer works ok, but you need all the divs to have the same parent and to have a wrapper, I have a solution that use javascript but works with any kind of element, they just need to have the same selector.
function setEqualHeight(selector, triggerContinusly) {
var elements = $(selector)
elements.css("height", "auto")
var max = Number.NEGATIVE_INFINITY;
$.each(elements, function(index, item) {
if ($(item).height() > max) {
max = $(item).height()
}
})
$(selector).css("height", max + "px")
if (!!triggerContinusly) {
$(document).on("input", selector, function() {
setEqualHeight(selector, false)
})
$(window).resize(function() {
setEqualHeight(selector, false)
})
}
}
setEqualHeight(".sameh", true)
http://jsfiddle.net/83WbS/2/
I would recommend reading this article that explains how to do what you are trying to do. I would put a fiddle up that shows, but its pretty extensive and pure css. http://matthewjamestaylor.com/blog/equal-height-columns-cross-browser-css-no-hacks
There is a much simpler solution I want to point to. Using large padding-bottom: 500em and negative margin-bottom:-500em of the same amount on columns while the wrapper has simply overflow:hidden to cut the columns to the right size.
Found here:
HTML/CSS: Making two floating divs the same height
As indicated by Hexodus you can padding-bottom and margin-bottom, but a better solution would be to use flexbox or grid.
You can check this codepen if you want. I included a footer area because that is something I needed and it required a little bit more of hack.
.section {
width: 500px;
margin: auto;
overflow: hidden;
padding: 0;
}
div {
padding: 1rem;
}
.header {
background: lightblue;
}
.sidebar {
background: lightgreen;
width: calc(25% - 1rem);
}
.sidebar-left {
float: left;
padding-bottom: 500rem;
margin-bottom: -500rem;
}
.main {
background: pink;
width: calc(50% - 4rem);
float: left;
padding-bottom: 500rem;
margin-bottom: -500rem;
}
.sidebar-right {
float: right;
padding-bottom: 500rem;
margin-bottom: -500rem;
}
.footer {
background: black;
color: white;
float: left;
clear: both;
margin-top: 1rem;
width: calc(100% - 2rem);
}
<div class="section">
<div class="header">
This is the header
</div>
<div class="sidebar sidebar-left">
This sidebar could have a menu or something like that. It may not have the same length as the other
</div>
<div class="main">
This is the main area. It should have the same length as the sidebars
</div>
<div class="sidebar sidebar-right">
This is the other sidebar, it could have some ads
</div>
<div class="footer">
Footer area
</div>
</div>
You can do this without using tables, by using this CSS trick.
Example - http://jsfiddle.net/LMGsv/
HTML
<div id="wrapper">
<div id="columns">
<div id="left">text</div>
<div id="right">text<br/>another line<br /></div>
</div>
</div>
CSS
#wrapper {
float:left;
width: 300px;
}
#columns {
float:left;
width:300px;
background:blue;
}
#left {
float:left;
width:50px;
background: blue;
}
#right {
width:250px;
background: red;
float:left
}