Change layout of elements using CSS without changing HTML - html

I have HTML markup that consists of three divs:
<div class="gallery">Gallery</div>
<div class="content">Content</div>
<div class="sidebar">Sidebar</div>
I want to present it in two different layouts using CSS (would be nicer if I could control whether the sidebar appears on left or right):
+------------------+
| Gallery |
+------+-----------+
| Side | Content |
| | |
+------+-----------+
+------+-----------+
| Side | Gallery |
+ +-----------+
| | Content |
| | |
+------+-----------+
In fact, it would be nicer if I could control whether the sidebar appears on left or right.
I can add additional divs and/or change the source order of divs as long as content appears before sidebar. But the HTML cannot be changed on per-layout basis.
Here is my incomplete attempt to solve the problem using flexbox + order property.
/* for demonstration */
.gallery { height: 100px; background-color: #CCC; }
.content { height: 200px; background-color: #EEE; }
.sidebar { height: 150px; background-color: #AAA; }
/* common */
.middle { display: flex; flex-direction: row; flex-wrap: wrap; }
/* layout-1 */
.middle.layout-1 .gallery { order: 1; width: 100%; }
.middle.layout-1 .content { order: 3; width: 75%; }
.middle.layout-1 .sidebar { order: 2; width: 25%; }
/* layout-2 */
.middle.layout-2 .gallery { order: 2; width: 75%; }
.middle.layout-2 .content { order: 3; width: 75%; }
.middle.layout-2 .sidebar { order: 1; width: 25%; }
<div class="middle layout-1">
<div class="gallery">Gallery</div>
<div class="content">Content (this layout works perfectly)</div>
<div class="sidebar">Sidebar</div>
</div>
<hr>
<div class="middle layout-2">
<div class="gallery">Gallery</div>
<div class="content">Content (should go below gallery)</div>
<div class="sidebar">Sidebar</div>
</div>

Check this demo if you have containing div like .middle.layout-2.
HTML:
<div class="middle layout-1">
<div class="gallery">Gallery</div>
<div class="content">Content (this layout works perfectly)</div>
<div class="sidebar">Sidebar</div>
</div>
<hr>
<div class="middle layout-2">
<div class="gallery">Gallery</div>
<div class="content">Content (should go below gallery)</div>
<div class="sidebar">Sidebar</div>
</div>
CSS:
/* for demonstration */
.gallery { height: 100px; background-color: #CCC; }
.content { height: 200px; background-color: #EEE; }
.sidebar { height: 200px; background-color: #AAA; }
/* common */
.middle { display: flex; flex-direction: row; flex-wrap: wrap; }
/* layout-1 */
.middle.layout-1 .gallery { order: 1; width: 100%; }
.middle.layout-1 .content { order: 3; width: 75%; }
.middle.layout-1 .sidebar { order: 2; width: 25%; }
/* layout-2 */
.middle.layout-2 { position: relative; }
.middle.layout-2 .gallery { width: 75%; margin-left: 25%; }
.middle.layout-2 .content { width: 75%; margin-left: 25%; }
.middle.layout-2 .sidebar { position: absolute; top: 0; left: 0; width: 25%; height: 100%;}

Normally I avoid floats like the plague, but for this case they do what you need.
If you want to switch the side the sidebar is on, just swap the lefts and rights.
This will keep your layout with dynamic sized content:
.gallery {
background: red;
}
.content {
background: green;
}
.sidebar {
background: blue;
}
/* layout1 */
.layout1 .gallery {
width: 100%;
}
.layout1 .content {
width: 75%;
float: right;
}
.layout1 .sidebar {
width: 25%;
float: left;
}
/* layout2 */
.layout2 .gallery {
width: 75%;
float: right;
}
.layout2 .content {
width: 75%;
float: right;
}
.layout2 .sidebar {
width: 25%;
}
<div class="layout1">
<div class="gallery">Gallery</div>
<div class="content">Content</div>
<div class="sidebar">Sidebar</div>
</div>
<br>
<br>
<br>
<div class="layout2">
<div class="gallery">Gallery</div>
<div class="content">Content</div>
<div class="sidebar">Sidebar</div>
</div>

Let me know if this is what you want:
HTML:
First Layout
<div class="container one">
<div class="gallery">Gallery</div>
<div class="sidebar">Sidebar</div>
<div class="content">Content</div>
</div>
<br/>Second Layout
<div class="container two">
<div class="gallery">Gallery</div>
<div class="sidebar">Sidebar</div>
<div class="content">Content</div>
</div>
<br/>Third Layout
<div class="container three">
<div class="gallery">Gallery</div>
<div class="sidebar">Sidebar</div>
<div class="content">Content</div>
</div>
<br/>
CSS:
html, body {
width:100%:height:100%:
}
* {
box-sizing:border-box;
white-space:nowrap;
}
.container {
width:500px;
height:500px;
position:relative;
}
.container div {
border:1px solid black;
padding:20px;
}
/*One*/
.one.container .sidebar, .one.container .content {
float:left;
width:50%;
}
.one.container:after {
clear:both;
display:block;
content:"";
}
/*Two*/
.two.container .sidebar {
float:right;
width:50%;
}
.two.container .content {
float:left;
width:50%;
}
.two.container:after {
clear:both;
display:block;
content:"";
}
/*Three*/
.three.container>div {
position:absolute;
}
.three.container .gallery {
top:0;
left:50%;
right:0;
height:50%;
}
.three.container .sidebar {
top:0;
left:0;
bottom:0;
width:50%;
}
.three.container .content {
top:50%;
left:50%;
right:0;
height:50%;
bottom:0;
}
Demo: http://jsfiddle.net/GCu2D/665/
This doesn't have additional div or markup. You need to just toggle the classe in the container.

Related

How to adjust three div one left and other two right side in css-flex-float?

I want to set three div one left side and other two left side but float: right; do not fix my problem. I am trying the flowing code.
.container .A {
float:left;
width:100px;
height: 80px;
background: lightskyblue;
}
.container .B {
float:right;
width:100px;
height: 80px;
background: lightgreen;
}
.container .C {
float:right;
width:100px;
height: 80px;
background: hotpink;
}
<div class="container">
<div class="A">A</div>
<div class="B">B</div>
<div class="C">C </div>
</div>
I want to set the div according to following image.
For Mobile view, I want to change the div like the following image
Here is the flex solution.
You can swap blocks using the order rule.
Also, I added a media query.
.container {
display: flex;
justify-content: flex-end;
width: 100%;
}
.container .A {
width:100px;
height: 80px;
background: lightskyblue;
margin-right: auto;
}
.container .B {
width:100px;
height: 80px;
background: lightgreen;
}
.container .C {
width:100px;
height: 80px;
background: hotpink;
}
#media (max-width: 767px) {
.container .A {
margin-right: unset;
order: 2;
}
.container .B {
order: 3;
}
.container .C {
order: 1;
margin-right: auto;
}
}
<div class="container">
<div class="A">A</div>
<div class="B">B</div>
<div class="C">C </div>
</div>
Try it using flexbox and media queries. I have used order property in media queries to change positions of boxes on small screen :)
CODEPEN LINK: https://codepen.io/emmeiWhite/pen/eYdQKgy
FULL CODE:
.container{
display:flex;
}
.container div{
margin:1rem;
}
.container .A {
width:100px;
height: 80px;
background: lightskyblue;
margin-right:auto;
}
.container .B {
width:100px;
height: 80px;
background: lightgreen;
}
.container .C {
width:100px;
height: 80px;
background: hotpink;
}
#media(max-width:768px){
.container .C{
order:-1;
margin-right:auto;
}
.container .A{
margin-right:1rem;
}
}
<div class="container">
<div class="A">A</div>
<div class="B">B</div>
<div class="C">C </div>
</div>
I have found one solution.
Please try with this code.
.container .A {
float: left;
width: 100px;
height: 80px;
background: lightskyblue;
}
.container .B {
float: right;
width: 100px;
height: 80px;
background: lightgreen;
}
.container .C {
float: right;
width: 100px;
height: 80px;
background: hotpink;
}
#media only screen and (max-width: 768px) {
.container .A {
float: right;
}
.container .C {
float: left;
}
}
<div class="container">
<div class="C">C</div>
<div class="B">B</div>
<div class="A">A</div>
</div>
Best regards.

How to create CSS box layouts?

I'm quite new to web development and I would like to create this in CSS and HTML:
I am unsure how to do this as I am only 13 and still learning.
What I have tried but failed miserably with:
.grey{
height:300px;
width:700px;
background-color: #e5e5e5;
z-index: 0;
}
.pink{
height:150px;
width:100px;
background-color:#ff8a8a;
padding-top: 0px;
padding-right:0px;
z-index: 1;
}
<div class="grey">
<div class="pink"> </div>
</div>
Use CSS-grid which is built-in within CSS. See code snippet.
.wrapper {
display: grid;
grid-template-columns:
40%
1fr
1fr
;
grid-template-rows:
100px
100px
;
grid-template-areas:
"box-1 box-2 box-4"
"box-1 box-3 box-5"
;
}
.box-1 {
grid-area: box-1;
background-color: grey;
}
.box-2 {
grid-area: box-2;
background-color: orange;
}
.box-3 {
grid-area: box-3;
background-color: lightblue;
}
.box-4 {
grid-area: box-4;
background-color: red;
}
.box-5 {
grid-area: box-5;
background-color: lightgreen;
}
<div class="wrapper">
<div class="box-1"></div>
<div class="box-2"></div>
<div class="box-3"></div>
<div class="box-4"></div>
<div class="box-5"></div>
</div>
Using flex:
.container {
display: flex;
justify-content: flex-start;
background-color: #e5e5e5;
}
.box {
height:150px;
width: 50%;
display: flex;
flex-wrap: wrap;
}
.square {
height: 50%;
width: 50%;
}
.square--pink {
background-color: #fb7378;
}
.square--orange {
background-color: #fcbd8b;
}
.square--blue {
background-color: #8ce0fd;
}
.square--green {
background-color: #7cff83;
}
<div class="container">
<div class="box"></div>
<div class="box">
<div class='square square--pink'></div>
<div class='square square--orange'></div>
<div class='square square--blue'></div>
<div class='square square--green'></div>
</div>
</div>
You should look over the css box model btw, it would help you better understand how to structure your HTML for your css :).
.grey{
height:300px;
width:600px;
background-color: #e5e5e5;
z-index: 0;
}
.pink{
height:150px;
width:150px;
background-color:#ff8a8a;
padding-top: 0px;
padding-right:0px;
z-index: 1;
float:right;
}
.green{
height:150px;
width:150px;
background-color:green;
padding-top: 150px;
padding-right:0px;
z-index: 1;
float:right;
}
.skyblue{
height:150px;
width:150px;
background-color:skyblue;
padding-top: 0px;
padding-right:0px;
z-index: 1;
float:right;
}
.orange{
height:150px;
width:150px;
background-color:orange;
padding-top: 150px;
padding-right:0px;
z-index: 1;
float:right;
}
<div class="grey">
<div class="green">
<div class="pink">
</div>
</div>
<div class="orange">
<div class="skyblue">
</div>
</div>
</div>
Here's a quick example:
<div class="container">
<nav class="nav left">left</nav>
<nav class="nav right">right</nav>
<nav class="nav right1">right</nav>
</div>
CSS:
.container {
display: flex;
flex-flow: row;
min-height: 50vh;
}
.left {
flex: 5;
background-color: grey;
width: 70%;
}
.right {
flex:2;
background-color: green;
}
.right1 {
flex:2;
background-color: red;
}
here is your solution.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
div { height: 102px; float:right; width: 150px;z-index: 2; }
.box{ width:600px;height:206px;background:grey;border:1px grey;z-index:0;float:left;}
.red { background: red; }
.green { background: green; }
.blue { background: blue; clear: right; }
.orange { background: orange; }
</style>
</head>
<body>
<div class="box">
<div class="red"></div>
<div class="green"></div>
<div class="blue"></div>
<div class="orange"></div>
</div>
</body>
</html>
With Flexbox, you can do something like this:
.grey {
display: flex; /* displays flex-items (children) inline */
justify-content: flex-end; /* places the flex-item (.innerFlex) to the end of the horizontal line */
height: 300px;
width: 700px;
max-width: 100%;
background: #e5e5e5;
}
.innerFlex {
display: flex;
flex-wrap: wrap; /* enables wrapping */
flex-basis: 200px; /* initial width set to 200px since its flex-items are 100px wide and you want them to wrap */
}
.pink {
flex-basis: 100px; /* initial width set to 100px */
height: 150px;
background: orange;
padding-top: 0;
padding-right: 0;
}
.pink:nth-child(2) {background: red}
.pink:nth-child(3) {background: blue}
.pink:nth-child(4) {background: green}
<div class="grey">
<div class="innerFlex"> <!-- additional wrapper -->
<div class="pink"></div>
<div class="pink"></div>
<div class="pink"></div>
<div class="pink"></div>
</div>
</div>
With the Grid:
.grey {
display: grid;
grid-template: 150px 150px / auto 100px 100px;
width: 700px;
max-width: 100%;
background: #e5e5e5;
}
.pink:nth-child(1) {grid-column: 2; background: orange}
.pink:nth-child(2) {background: red}
.pink:nth-child(3) {grid-column: 2; background: blue}
.pink:nth-child(4) {background: green}
<div class="grey">
<div class="pink"></div>
<div class="pink"></div>
<div class="pink"></div>
<div class="pink"></div>
</div>

CSS 2 Floating Div's Inside Container Full Height w/ Image

I have a container thats 900px wide with 2 floating divs inside. I need to make column 2 background full height and dependent to the image to the left. The text in column 2 also needs to be vertically centered, again based on image height.
https://jsfiddle.net/rj5o6n79/1/
<div class="wrapper">
<div class="col span_2_of_3 content">
<img src="http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg" />
</div>
<div class="col span_1_of_3 box2">
This is column 2
</div>
<div style="clear:both;"></div>
</div>
You can use jQuery to get the height of the left div
var leftDivHeight = $('.span_2_of_3').height();
$('.span_1_of_3').css('height',leftDivHeight);
then wrap the content of your inner div to another div
<div class="col span_1_of_3 box2">
<div class='innerContent'> This is column 2 </div> <!-- added div -->
</div>
then add this css to vertically center your inner div
.innerContent{
position: relative;
top: 50%;
transform: translateY(-50%);
}
JSFIDDLE DEMO
Is this what you want?
body { margin:0; padding:0; }
.wrapper { border:1px solid green; width:900px; margin:0px auto; }
.content {
width: 100%; /* or whatever is required */
text-align: center; /* ensures the image is always in the h-middle */
overflow: hidden; /* hide the cropped portion */
}
img {
position: relative; /* allows repositioning */
/*left: 100%; move the whole width of the image to the right */
/* margin-left: -200%; magic! */
float:left;
}
/* COLUMN SETUP */
.col {
display: block;
float:left;
margin:0;
}
.col:first-child { margin-left: 0; }
.box { background-color: #ccc; }
.box2 { background-color: red; }
/* GROUPING */
.group:before,
.group:after {
content:"";
display:table;
}
.group:after {
clear:both;
}
.group {
zoom:1; /* For IE 6/7 */
}
/* GRID OF THREE */
.span_3_of_3 {
width: 100%;
}
.span_2_of_3 {
width: 66.1%;
}
.span_1_of_3 {
width: 33.8%;
height: 400px;
}
.content {
position: relative;
top: 50%;
text-align:left;
}
<div class="wrapper">
<div class="col span_2_of_3 content">
<img src="http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg" />
</div>
<div class="col span_1_of_3 box2">
<div class="content">
This is column 2
</div>
</div>
<div style="clear:both;"></div>
</div>
I think, I have more or less found what you are looking for. Though the second column isn't full height it is vertically centered and just as big as it needs to be.
.wrapper {
width: 900px;
border: 1px solid #000000;
display: inline-block;
}
.col img{
display: block;
}
.content {
vertical-align: middle;
display: inline-block;
}
.box2 {
display: inline-block;
vertical-align: middle;
}
<div class="wrapper">
<div class="col span_2_of_3 content">
<img src="http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg"/>
</div>
<div class="col span_1_of_3 box2">
This is column 2
</div>
<div style="clear:both;"></div>
</div>
I have a solution of your problem checkout this demo, I think it's working for you. Here is the code:
body { margin:0; padding:0; }
.wrapper {
border: 1px solid green;
width: 900px;
margin: 0px auto;
/* background: #f00; */
display: table;
table-layout: fixed;}
.content {
width: 100%; /* or whatever is required */
text-align: center; /* ensures the image is always in the h-middle */
overflow: hidden; /* hide the cropped portion */
}
img {
position: relative; /* allows repositioning */
left: 100%; /* move the whole width of the image to the right */
margin-left: -200%; /* magic! */
}
/* COLUMN SETUP */
.col {
display: table-cell;
vertical-align: middle;
}
.col:first-child { margin-left: 0; }
.box { background-color: #ccc; }
.box2 { background-color: red; }
/* GROUPING */
.group:before,
.group:after {
content:"";
display:table;
}
.group:after {
clear:both;
}
.group {
zoom:1; /* For IE 6/7 */
}
/* GRID OF THREE */
.span_3_of_3 {
width: 100%;
}
.span_2_of_3 {
width: 66.1%;
}
.span_1_of_3 {
width: 33.8%;
}
td{ background:#000; color:#fff;}
<div class="wrapper">
<div class="col span_2_of_3 content">
<img src="http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg" />
</div>
<div class="col span_1_of_3 box2">
This is column 2
</div>
<div style="clear:both;"></div>
</div>

Different width divs in the same row

I'm trying to put 3 divs(with different widths respectively : 10%,70% & 20%) in the same row but the middle one always go full width of the page.
Here is my code:
#left-bar {
width: 10%;
background-color: #FF0000;
}
#middle-bar {
width: 70%;
background-color: #6600FF;
}
#right-bar {
width: 20%;
background-color: #99FF99;
}
<div class="row">
<div id="left-bar"></div>
<div id="middle-bar"></div>
<div id="right-bar"></div>
</div>
By default div is a block level element that's why they aren't in the same row.
You have a few options to fix this:
option with CSS flexbox:
.row {
display: flex;
width: 100%
}
.row>div {
/*demo purposes */
height: 30px;
}
#left-bar {
flex: 0 10%;
background-color: #F00;
}
#middle-bar {
flex: 1;
background-color: #60F;
}
#right-bar {
flex: 0 20%;
background-color: #9F9;
}
<div class="row">
<div id="left-bar"></div>
<div id="middle-bar"></div>
<div id="right-bar"></div>
</div>
(old options)
option with display:inline-block
.row {
/*fix inline-block gap*/
font-size: 0;
}
.row>div {
display: inline-block;
/*demo purposes */
height: 30px;
}
#left-bar {
width: 10%;
background-color: #F00;
}
#middle-bar {
width: 70%;
background-color: #60F;
}
#right-bar {
width: 20%;
background-color: #9F9;
}
<div class="row">
<div id="left-bar"></div>
<div id="middle-bar"></div>
<div id="right-bar"></div>
</div>
option with display:table-[cell]
.row {
display: table;
width: 100%
}
.row>div {
display: table-cell;
/*demo purposes */
height: 30px;
}
#left-bar {
width: 10%;
background-color: #F00;
}
#middle-bar {
width: 70%;
background-color: #60F;
}
#right-bar {
width: 20%;
background-color: #9F9;
}
<div class="row">
<div id="left-bar"></div>
<div id="middle-bar"></div>
<div id="right-bar"></div>
</div>
The table-cell option actually doesn't work in some internet explorer versions. But the same result can be achieved with the property float:
#left-bar{
width:10%;
background-color: #FF0000;
}
#middle-bar{
width:70%;
background-color: #6600FF;
}
#right-bar{
width:20%;
background-color: #99FF99;
}
.row > div {float:left;}
<div class="row">
<div id="left-bar">a</div>
<div id="middle-bar">b</div>
<div id="right-bar">c</div>
</div>
#left-bar{
width:10%;
background-color: #FF0000;
float:left;
}
#middle-bar{
width:70%;
background-color: #6600FF;
float:left;
}
#right-bar{
width:20%;
background-color: #99FF99;
float:left;
}
If that doesn't work, please provide more html and css because the problem will be somewhere else. Also, verify that you have heights set for your divs.

Div content in wrong position

I'm trying to put 3 divs in the same row as the following code.
My CSS and HTML:
.row {
display: table;
width: 100%
}
.row > div {
display: table-cell;
height:30px; /*demo purposes */
}
#left-bar {
width: 10%;
background-color: #FF0000;
}
#middle-bar {
width: 70%;
background-color: #6600FF;
}
#right-bar {
width: 20%;
background-color: #99FF99;
}
<div class="row">
<div id="left-bar"> here I have an accordion </div>
<div id="middle-bar"> heve a have my canvas </div>
<div id="right-bar"> and here I have an editor</div>
</div>
Somehow the content of the middle-bar(my canvas) is positioned in the correct place, but the other two divs contents are in the bottom of the page as you can see here see photo. Do you guys know why this is happening?
After discussing the project further with you in the comments, and in chat, I think you should take an approach that uses flexbox instead. The code is fairly straight forward:
.container {
display: flex;
}
.left { flex-basis: 10%; background: #F99; }
.right { flex-basis: 20%; background: #99F; }
.middle { flex-basis: 70%; background: #9F9; }
<div class="container">
<div class="left">L</div>
<div class="middle">C</div>
<div class="right">R</div>
</div>
I only managed width.
There's nothing problematic see this.
.row {
display: table;
width: 100%
}
.row > div {
display: table-cell;
height:30px; /*demo purposes */
}
#left-bar {
width: 20%;
background-color: #FF0000;
}
#middle-bar {
width: 60%;
background-color: #6600FF;
}
#right-bar {
width: 20%;
background-color: #99FF99;
}
<div class="row">
<div id="left-bar"> here I have an accordion </div>
<div id="middle-bar"> heve a have my canvas </div>
<div id="right-bar"> and here I have an editor</div>
</div>