So i have a traditional three column lay-out. The left column is like a toolbox column, the middle column is the "dynamic content" column and the right one is like a summary of data column.
What i want to achieve is that as soon as some responsiveness is going on that the center column will be on top. This will be the most important part of the website and thus should be on top. I cant seem to get this to work with bootstrap. This is my lay-out:
<div class="container">
<!-- Example row of columns -->
<div class="row">
<!-- column: left -->
<div class="col-md-2" id="sidebarleft">left </div>
<!-- column: center-->
<div class="col-md-8" id="main">middle</div>
<!-- column: right -->
<div class="col-md-2" id="sidebarright">right</div>
</div>
</div>
So how would i go about achieving this?
Thanks!
This should do the trick.
So the layout is intact when the browser is using Bootstrap's "md" viewport, however when made smaller (so "sm" and "xs") the middle column is at the top followed by the left and right.
<div class="container">
<!-- Example row of columns -->
<div class="row">
<!-- column: center-->
<div class="col-md-8 col-md-push-2" id="main">middle</div>
<!-- column: left -->
<div class="col-md-2 col-md-pull-8" id="sidebarleft">left </div>
<!-- column: right -->
<div class="col-md-2" id="sidebarright">right</div>
</div>
That's because your HTML is stacking in order of the way it's written.
A good way to achieve this would be to either:
a) Take a dropdown UI approach on the #sidebarleft or, b) Use JS to refactor the layout when responsive. Though, depending how much your site relies on JS, this may not be suitable from a no-js point of view. It would need a fallback. I'm not entire too sure on CSS methods with Bootstrap using the push/pull class selectors.
A jQuery solution would be to store the element ID in a variable and then tell the DOM to remove the element at a certain width. Then, tell it to insertBefore or insertAfter the #sidebarleft element.
var mainContent = $('#main');
var leftSidebar = $('#sidebarleft');
$(window).resize(function() {
if ($(window).width() <= 480) {
mainContent.remove();
mainContent.insertBefore(leftSidebar);
} else if ($(window).width() > 481) {
mainContent.remove();
mainContent.insertAfter(leftSidebar);
}
});
Here's a Pen on the functionality in JS using jQuery.
Resize the screen to less or equal than 480 pixels and watch the main content reorder itself above the sidebar.
I wrote this and worked great for me. The middle column goes to the left on mobile. The 3rd one goes down on tablet.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.container {
width: 100%;
max-width: 1140px;
margin: 15px auto;
}
.col {
margin-bottom: 10px
}
.rowone {
width: 75%;
float: left;
}
.rowtwo {
width: 24%;
float: right;
}
.middle {
float: right;
width: 66.6%;
background: #fe8a9e
}
.left {
float: left;
width: 32%;
background: #64c780
}
.right {
float: left;
width: 100%;
background: #4690ec
}
#media (max-width: 860px) {
.rowone, .rowtwo {
width: 100%;
}
.left {
float: right
}
.middle {
float: left
}
.right .module.long {
height: 218px;
}
}
#media (max-width: 500px) {
.col, .rowone, .rowtwo {
width: 100%;
}
.middle {
float: left
}
.left {
float: right
}
.rowtwo {
float: left
}
}
</style>
</head>
<body>
<div class="container">
<div class="rowone">
<div class="col middle">Middle</div>
<div class="col left">Left</div>
</div>
<div class="rowtwo">
<div class="col right">Right</div>
</div>
</div>
</body>
</html>
Related
I've read quite a few similar questions to mine but none is quite the same or has an answer which works for me.
I'm using Twitter Bootstrap 3. I have two rows, and each row contains a col-sm-12 div, so they're the same width. The content in the first row is wider than its container but I have overflow:auto set on the element containing the two rows so a horizontal scrollbar is displayed and the content can be seen using that, so that's fine.
In the second row I have a div to which I'm applying a jQuery plugin (jqxGrid, for what it's worth). I've set the width option of the plugin to be "100%". The resultant grid's content is also too wide for its container but because of the way the jQuery plugin creates the grid it constricts the grid's width to 100% of its parent's width rather than overflowing.
So what I really need is for the .row elements to all be as wide as the widest overflowing content so that when the jQuery plugin evaluates the width of its parent so as to set its own width, the resultant grid ends up being as wide as the overflowing content in the first row.
I've made a fiddle which I hope will illustrate the problem. I feel that at its heart this is a CSS problem so a pure CSS solution would be excellent, but I doubt that that's possible.
.wrapper {
color: #fff;
padding: 10px;
}
.container-fluid {
background-color: #333;
overflow: auto;
}
.row1 {
background-color: yellow;
}
.row2 {
background-color: orange;
}
.short-content {
background-color: red;
width: 100%;
}
.long-content {
width: 2000px;
background-color: blue;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="wrapper">
<div class="container-fluid">
<div class="row row1">
<div class="col-sm-12">
<div class="long-content">
Long content
</div>
</div>
</div>
<div class="row row2">
<div class="col-sm-12">
<div class="short-content">
THe jQuery plugin here is too wide to fit but won't overflow because its width is set to match its parent.
</div>
</div>
</div>
</div>
</div>
To my understanding, wrapping each .col-sm-12 into their own parent .row is a verbose way of having all .col-sm-12 in a single .row container, as .col-sm-12s are always wrapping into a new line.
So, in case your setup allows for removing the intermediate .row tags, the only additional line of css you have to write is float: left; on .row. (In the example below I used the id #custom on .container-fluid to isolate this modification from the rest of your page).
body {
color: #fff;
padding: 10px;
}
.container-fluid {
background-color: #333;
overflow: auto;
}
.row1 {
background-color: yellow;
}
/*.row2 {
background-color: orange;
}*/
.short-content {
background-color: red;
width: 100%;
}
.long-content {
width:2000px;
background-color: blue;
}
#custom .row {
float: left;
}
<div id="custom" class="container-fluid">
<div class="row row1">
<div class="col-sm-12">
<div class="long-content">
Long content
</div>
</div>
<!-- </div> -->
<!-- <div class="row row2"> -->
<div class="col-sm-12">
<div class="short-content">
THe jQuery plugin here is too wide to fit but won't overflow because its width is set to match its parent.
</div>
</div>
</div>
</div>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="sidebar">
<div class="title"></div>
<div class="related"></div>
</div>
<div class="description"></div>
As you can see, there are 2 parent divs, sidebar and description, and 2 child divs within sidebar. I have given css rules for them and looks like this picture below :
Question : how can I make the view like this with those markup without change the markup ? :
*Note : the second will be view if the window's width <= 320px. I have used #media query but the problem is, title and related are within the one parent (sidebar), so it was difficult for me to make them separated and move description in the middle of them.
Thanks
This might not be a smart way, but the code below could be a solution for your problem:
HTML:
<div class="sidebar">
<div class="title"></div>
<div class="description2"> description ...</div>
<div class="related"></div>
</div>
<div class="description"> description ... </div>
CSS:
.description2{
display:none;
}
#media only screen and (max-width: 320px) {
.description{
display:none;
}
.description2{
display:block;
}
}
Hope this helps.
I don't think it can be done keeping the two divs within the sidebar (without using javascript). However you can do it like this which makes more sense to me, as it places the description immediately after the title.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Media query</title>
<style>
.title,
.description,
.related {
background-color: #333;
margin: 5px;
}
#media only screen
and (min-width : 620px) {
.holder {
width: 620px;
}
.title {
float: right;
width: 200px;
height: 200px;
}
.description {
float: left;
width: 400px;
height: 600px;
}
.related {
float: right;
width:200px;
height: 390px;
}
}
</style>
</head>
<body>
<div class="holder">
<div class="title"></div>
<div class="description"></div>
<div class="related"></div>
</div>
</body>
</html>
I'm realizing more and more that I don't have a good understanding of css positioning. Seeing that this often causes problems for me, I've been attempting to create different layouts just for practice. I'm trying to create a website that could hold 6 different divs that display 6 different data points. Two large divs and the top each covering 50% of the screen, 4 smaller divs below each covering 25% of the screen.
I did some research and found that float left would give me the results for the top half, but I can't seem to figure out how to position the the bottom four divs so that they stay flushed with the divs above and to side. Everything that I've tried so far fails whenever I resize the screen. Can someone point me in the right direction please?
here is a pic of what I have so far. The top half is right, the bottom half is what i'm stuck on
here is my html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>flatpage</title>
<link rel="stylesheet" href="css.css">
<div id ="main">
<div class = "navbar">
</div>
<div class = "total_number_container">
</div>
<div class = "searched_number_container">
</div>
<div class = "attribute_one>"
</div>
<div class = "attribute_two>"
</div>
<div class = "attribute_three>"
</div>
<div class = "attribute_four>"
</div>
</div>
</head>
<body>
<script src="js/scripts.js"></script>
</body>
</html>
here is my css
body {
background-color:#ecf0f1;
margin:0;
}
.navbar{
background-color:#2c3e50;
width: 100%;
height: 50px;
margin:0;
padding:0;
}
.total_number_container {
background-color:#3498db;
float: left;
width: 50%;
height: 300px;
}
.searched_number_container {
float:left;
background-color:#2980b9;
width: 50%;
height: 300px;
}
.attribute_one {
background-color:#5C97BF;
width: 25%;
height: 300px;
}
.attribute_two {
background-color:#34495e;
width: 25%;
height: 300px;
}
.attribute_three {
background-color:#5C97BF;
width: 25%;
height: 300px;
}
.attribute_four {
background-color:##34495e;
width: 25%;
height: 300px;
}
This fiddle corrects syntax mistakes in the original HTML and CSS code, and uses the original classes (.attribute_one, .attribute_two, .attribute_three, .attribute_four) to achieve the desired results.
http://jsfiddle.net/2G8C7/
The key things missing were:
.attribute_one, .attribute_two, .attribute_three, .attribute_four {
float: left;
}
And the following HTML syntax mistake:
<div class = "attribute_one>" <!-- notice the closing quote is in the wrong place -->
</div>
which should be
<div class = "attribute_one">
</div>
Also there was a typo in the CSS, where the background-color for .attribute_four had two #'s (##34495e)
You mean, something like the below?
This can be achieved using floats and % sizing.
Demo Fiddle
HTML
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
CSS
html, body {
width:100%;
height:100%;
margin:0;
padding:0;
}
div:nth-child(1), div:nth-child(2) {
width:50%;
}
div {
box-sizing:border-box;
float:left;
border:1px solid black;
width:25%;
height:50%;
}
<div class = "attribute_one>"
</div>
<div class = "attribute_two>"
</div>
<div class = "attribute_three>"
</div>
<div class = "attribute_four>"
</div>
Above is a part from your HTML and is wrong. What you want is
<div class = "attribute_one">
</div>
<div class = "attribute_two">
</div>
<div class = "attribute_three">
</div>
<div class = "attribute_four">
</div>
After that just use float:left for all four divs ans set the width to 25%. And after that is a best practice to put another div
<div style="clear:both"></div>
I'm trying to align the layout so the images align in a row.
Here's a image of what it is currently doing
HTML
<div class="p-alignleft"></div>
<div class="p-alignright"></div>
CSS
.p-alignleft {
float: left;
margin-right:40px;
width:450px;
font-size: 1.2em;
line-height: 1.4em;
}
.p-alignright {
float: right;
width:450px;
font-size: 1.2em;
line-height: 1.4em;
}
By looking at the captured screen, I think you should enclose each person's part inside a div, and give them classes .p-alignleft or .p-alignright. After every two of them, make an empty <div class="clear"></div> with style .clear {clear:both}, so the next two persons will align at the same vertical level
HTML:
<div class="p-alignleft">Person A</div>
<div class="p-alignright">Person B</div>
<div class="clear"></div>
<div class="p-alignleft">Person C</div>
<div class="p-alignright">Person D</div>
CSS:
.p-alignleft {float:left}
.p-alignright {float:right}
.clear {clear:both}
If I understand rightly, you have a couple of options here. Instead of floating, my preference is to set each div to display: inline-block; That will make the divs line up next to each other, even if one is taller than the other:
div {
display: inline-block;
vertical-align: top;
}
A working example: http://cdpn.io/ojDEl
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
.wrap {width: 800px;}
.wrap div {width: 48%; display: inline-block; vertical-align: top; background: #e7e7e7; margin-bottom: 20px;}
/* temp demo styles */
.wrap div {height: 200px;}
.wrap div.test {height: 300px;}
</style>
</head>
<body>
<div class="wrap">
<div>Person A</div>
<div class="test">Person B</div>
<div>Person C</div>
<div>Person D</div>
</div>
</body>
</html>
Use a container div as a row element <div class="row clearfix"><div class="media">...</div></div>
Float both elements to the left, and set clear: left on the odd ones.
Use a javascript solution to set the height to be the same. then you can leave the clear left, right, or clear all to one side.
something like this, you probably need to tweak it, it's more like pseudo code.:
var maxHeight = 0;
var items = $('.media');
// get the max height of the items
items.each(function() {
var height = parseInt($(this).outerHeight().replace('px', ''), 10);
if (maxHeight < height) {
height = maxHeight;
}
});
// assign the height to all the items
items.height(height + 'px');
Five of us have spent a day and a half working on this - got some very close solutions, but seems like it might be impossible to do without pulling in Javascript.
Scenario
We're using a responsive (media-query based), 960 grid layout. There are four divs with content. These four divs need to semantically be in the order shown in the image below. Since it is the 960 grid, we also have wrapper divs per "row" - like this:
<div id="topzone">
<div id="one">1</div>
<div id="two">2</div>
</div>
<div id="bottomzone">
<div id="three">3</div>
<div id="four">4</div>
</div>
Div one has the intro to an article, div two has an advertisement, div three has the actual article and div four has random stuff (facebook feeds, whatever).
On mobile, the divs need to display in order from one to four. On desktop they need to display the same, but in two columns, horizontally ordered first.
So far so good. Here is the kicker:
We don't know what height the divs will be - they will vary with each page (even the advertisement one).
There can't be any vertical gaps between divs.
We can't use Javascript (or really, really, really don't want to - we know we can do this easily with JS)
If you just do floats left and right you get gaps:
<div id="topzone">
<div id="one" style="float: left; height: 300px">1</div>
<div id="two" style="float: right; height: 200px">2</div>
</div>
<div id="bottomzone">
<div id="three" style="float: left; height: 100px">3</div>
<div id="four" style="float: right; height: 300px">4</div>
</div>
Attempted Solutions
CSS tables don't allow for rowspans. Workarounds either have the empty div get overlayed or leave gaps.
Masonry CSS orders the divs vertically so mobile would incorrectly drop divs two and four below one and three.
The closest we came was hijacking the overflow property to display the third div below the first one. This worked brilliantly - until we tried to add a footer to the page. Because overflow has no height according to the browser, the footer overlayed the third div.
<style type="text/css">
#one {
height: 300px;
background-color: yellow;
}
#two {
height: 200px;
background-color: brown;
}
#three {
background-color: blue; /* only shows in mobile, otherwise hidden behind #one */
}
#three-inner {
height: 100px;
border: 2px solid black;
}
#four {
height: 300px;
background-color: burlywood;
}
/* Non-mobile */
#media all and (min-width: 740px) and (min-device-width: 740px),
(max-device-width: 800px) and (min-width: 740px) {
#one {
float: left;
width: 50%;
}
#two {
float: right;
width: 50%;
}
#three {
height: 0px; /* turns into overflow */
width: 50%;
}
#three-inner {
clear: left;
}
#four {
float: right;
width: 50%;
clear: right;
}
}
</style>
<div id="topzone">
<div id="one">
<p><strong>First block.</strong></p>
</div>
<div id="two">
<strong>Second block</strong>
</div>
<div id="bottomzone">
<div id="three">
<div id="three-inner">
<p><strong>Third block.</strong></p>
</div>
</div>
<div id="four">
<p><strong>Fourth block.</strong></p>
</div>
</div>
</div>
There must be a way to do this in all CSS - tell me there is?