CSS responsive nested grid height - html

I am currently teaching myself how to setup a responsive grid layout that will automatic adjust on the device size. So far so good, but I am having an issue with the the height of some of the boxes not adjusting. See here for the code http://jsfiddle.net/shuka/tbe32q3h/
html
<body>
<div id="section2">
<div class="container grid2">
<article class="col half">MAP</article>
<article class="col half" style="background-color:#069;">
<div class="grid2">
<article class="col quater">BOX 1</article>
<article class="col quater">BOX 2</article>
</div>
<div class="grid2">
<article class="col quater">BOX 3</article>
<article class="col quater">BOX 4</article>
</div>
</article>
<br/>
</div>
CSS
body {
margin: 0;
padding: 0;
}
#section1 br,#section2 br,#section3 br, #topbar br {
clear: both;
}
.container {
margin: auto;
max-width: 1400px;
overflow:hidden;
}
.col {
background: #eee;
float: left;
margin-left: 1.4%;
margin-bottom: 20px;
}
.grid2 .col {
width: 49.3%;
}
.grid2 .half {
/*width: 48.4%;*/
height:49.3vw;
/*max-width:678px;*/
max-height:690px;
/*float:left;*/
position:relative;
}
.grid2 .quater {
margin-left: 2.1%;
margin-bottom: 2.1%;
width: 48.95%;
height:48.95vw;
/*max-width:317px;*/
max-height:338px;
/* float:left;*/
position:relative;
}
.grid4 .col:nth-of-type(4n+1), .grid3 .col:nth-of-type(3n+1), .grid2 .col:nth-of-type(2n+1) {
margin-left: 0;
clear: left;
}
As you can see when you resize the big boxes change, however the issue is with the 4 smaller boxes, the width changes but the height stay the same. I would like the four boxes to keep as square but get small when the screen is resized, if anyone can spot something I have missed it be greatly appreciated.
Cheers
Shuka

This is a tricky layout to pull off, but I did a little playing around and I think I have something that will work for you:
http://jsfiddle.net/CaseyRule/h0drc99g/
I decided to treat the max-width scenario with hard-coded numbers, like this:
#media (min-width: 900px) { /* max-width of container */
.half {
height: 450px; /* max-width * 50% */
}
.half.col1 {
width: 432px; /* max-width * 48% */
}
.half.col2 {
width: 450px; /* max-width * 50% */
}
.quarter {
width: 216px; /* max-width * 24% */
height: 216px; /* max-width * 24% */
}
.half.col1, .quarter.col1 {
margin-right: 18px; /* max-width * 2% */
}
.row1 .quarter {
margin-bottom: 18px; /* max-width * 2% */
}
}
I did this with a max-width of 900px, just so you could see how it works more easily within the jsfiddle screen, but it is easy to change this to 1400px as you had it originally. Just change the max-width of the container, and calculate the numbers within the media query as indicated in the comments. Alternatively, you could automate all of these calculations with a pre-processor like LESS, which I would strongly encourage.

Related

Div float keep fixed and 100% height of the viewport

I am trying to make a basic responsive structure for a website with CSS. So far I have managed to make three column divs, a menu, a sidebar and one for content.
What I would like to achieve now is to have the menu and the sidebar to be 100% of the viewport height and fixed so that the content div is "scrollable" but the menu and the sidebar stays on top no matter how much content there is in the col content column. Naturally, I do not want this to happen in the media query though.
How can I achieve this most efficiently with CSS. Do I have to restructure the divs in HTML or is there any way to achieve this with CSS?
/* SECTIONS */
.section {
clear: both;
}
/* COLUMN SETUP */
.col {
display: block;
float: left;
}
/* GRID OF THREE */
.menu {
width: 33%;
background-color: #98D2ED
}
.sidebar {
width: 33%;
background-color: #D3ADAD
}
.content {
width: 33%;
background-color: #C9E4D1
}
/* GO FULL WIDTH BELOW 480 PIXELS */
#media only screen and (max-width: 480px) {
.menu {
width: 100%;
}
.sidebar {
width: 100%;
}
.content {
width: 100%;
}
}
<div class="section">
<div class="col menu">
<p>
Menu
</p>
I want this cloumn to be fixed and full height of the viewport when the screen size is above 480px.
</div>
<div class="col sidebar">
<p>
Sidebar
</p>
I want this cloumn to be fixed and full height of the viewport when the screen size is above 480px.
</div>
<div class="col content">
Content
</div>
</div>
What I am trying to achieve:
You can use flexbox, either for known/unknown width and height elements, The key is to set the content area to overflow:auto, and switch the flex-direction to column in media queries.
jsFiddle
html, body {
height: 100%;
}
body {
margin: 0;
display: flex;
}
.content {
flex: 1;
overflow: auto;
}
.menu { background: grey; }
.sidebar { background: silver; }
#media (max-width: 480px) {
body {
flex-direction: column;
}
}
<div class="menu">Menu</div>
<div class="sidebar">Sidebar</div>
<div class="content">
<!-- scroll test -->
<div style="height:1000px;">Content</div>
</div>
Or, the traditional way to set the menu and sidebar to position:fixed.
jsFiddle
html, body {
height: 100%;
margin: 0;
}
body {
margin-left: 200px;
}
.menu, .sidebar {
position: fixed;
top: 0;
height: 100%;
overflow: auto;
}
.menu {
left: 0;
width: 100px;
background: grey;
}
.sidebar {
left: 100px;
width: 100px;
background: silver;
}
.content {
overflow: auto;
}
#media (max-width: 480px) {
body {
margin: 100px 0 0;
overflow: hidden;
}
.menu, .sidebar {
left: 0;
width: 100%;
height: 50px;
}
.sidebar {
top: 50px;
}
.content {
height: calc(100% - 100px);
}
}
<div class="menu">Menu</div>
<div class="sidebar">Sidebar</div>
<div class="content">
<!-- scroll test -->
<div style="height:1000px;">Content</div>
</div>
As I understand, you want your .menu and .sidebar to be stuck to the screen in one place and have the content be scrollable. And add some more code to other things as well, I know that sounds vague, but it would be a waste of time to write everything down, as I have edited you I finished copy, and I have notes that explain all my changes (and the reasons for doing so) in the code below.
I removed the floats and their classes, as I believe those are not necessary, and that the floats do more harm than good. As well as moved the .content to be in the middle column (between .menu and .sidebar). However, if you need to, feel free to change any or al of these things back.
Here's the updated code: (and here's a JSFiddle: JSFiddle)
I know that .menu has a weird space above it (when running the snippet and the JSFiddle), but I have it live on my website here, and it behaves perfectly fine, and uses the same code.
* {
margin: 0px; /* Added to remove margin from everything */
padding: 0px; /* Added to remove margin from everything */
}
.section, .menu, .sidebar, .content {
display:inline-block !important; /* Added so they will line up next to each other */
}
.section {width:100%;} /* Pretty self explanatory, added to set ".section" to a width of 100% */
/* GRID OF THREE */
.menu {
width: 33%; /* Was already here */
background-color: #98D2ED; /* Was already here */
height:100vh; /* Makes it be 100% of the Viewport Height, or 100% of the browser window height */
position: fixed; /* Makes it stay "fixed" to one place on the screen */
}
.sidebar {
width: 33%; /* Was already here */
background-color: #D3ADAD; /* Was already here */
position:absolute; top:0px; left: 67%; /* To make the element in the right place, add the width of "menu" and "content" */
height:100vh; /* Makes it be 100% of the Viewport Height, or 100% of the browser window height */
position: fixed; /* Makes it stay "fixed" to one place on the screen */
}
.content {
width: 34%; /* Was already here, but changed it to 34 to make the website fill the page */
background-color: #C9E4D1; /* Was already here */
position:absolute; top:0px; left:33%; /* To make the element in the right place, make this the width of "menu" */
}
/* The CSS below this was already here */
/* GO FULL WIDTH BELOW 480 PIXELS */
#media only screen and (max-width: 480px) {
.menu { width: 100%; }
.sidebar { width: 100%; }
.content { width: 100%; }
}
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<div class="section">
<div class="menu">
Menu
</div>
<div class="content">
Content
</div>
<div class="sidebar">
Sidebar
</div>
</div>
Really Hope that helped!

Container height no longer than screen-header

I asked a question today about good and bad practises in CSS/HTML/jQuery and when it is appropriate to use jQuery to set container dimensions. I got some good answers
So, understanding that jQuery is not the best option, I decided to ask maybe some of you can give some input about this "problem"
So, I have a page put together with php. I have one header for all of my pages and content is being changed with php (I am saying this only to let you guys know that wrapping header and div in one container is not an option):
include ("header.php");
include ("$lang/$section.php");
include ("footer.php");
I have a header with fixed hight (100px + 100px margin-bottom) and after that I have a div which on screens smaller than 768px(height) I want to be no longer than the remaining space. If the screen is larger, I want my div to be
max-height: 420px;
with
padding: 100px 0;
Inside of this div I have 3 floated columns. I need them to fill the space in the parent div.
What I would usually do is- use jQuery and calculate screen height and subtract header height and all the margins and paddings. But as I've learned today, that is not a good practise.
So, to wrap it up: I NEED THE DIV TO FILL THE SPACE BETWEEN HEADER AND BOTTOM OF THE SCREEN FOR VIEWPORT HEIGHT SMALLER THAN 768px. MAX-HEIGHT FOR THIS DIV IS 420px. With jQuery it is super easy but I can't figure out the clean css way.
Maybe some of you have an idea?
Here is my fiddle, so you guys don't have to type out all of the code.
Thank you in advance!
You can use calc() and vh (viewport height).
calc() browser support: http://caniuse.com/#search=calc
vh browser support: http://caniuse.com/#search=vh
So we use calc(100vh - 200px) being 100vh the height of the viewport and 200px the height of the header.
Also, we add a media query so that when the screen is bigger than 768px height we limit the height to 420px.
Try this:
header { height: 100px; background: #ccc; margin-bottom: 100px; box-sizing: border-box; }
section { width: 100%; height: calc(100vh - 200px); padding: 50px 0; background: yellow; box-sizing: border-box; }
.col1, .col2, .col3 { float: left; width: 33%; }
.colPadding { padding: 25px; background: blue; }
.cb { width: 100%; height: 1px; clear: both; }
body {
margin: 0;
}
#media screen and (min-height: 768px) {
section {
max-height: 420px;
}
}
<header>
This is my header with 100px bottom margin
</header>
<section>
<div class="col1">
<div class="colPadding">
section with padding: 50px 0; and max-height: 420px;
</div>
</div>
<div class="col2">
<div class="colPadding">
Column 2
</div>
</div>
<div class="col3">
<div class="colPadding">
Column 3
</div>
</div>
<div class="cb"></div>
</section>
Gave it a shot with CSS3 flex-box model and screen media queries. Here is my fiddle.
I used 300px instead of 764px for the fiddle. (you can change it if you want, I just used 300px so that it's easier to test)
Applied CSS
* { box-sizing: border-box; } /* force sizing based on border */
body {
display: flex; /* flex for body since wrapping header and section is not allowed */
flex-flow: column wrap;
}
header {
height: 100px;
background: #ccc;
margin-bottom: 100px;
flex: 0 0 auto; /* make header size fixed */
}
section {
width: 100%;
max-height: 420px;
padding: 50px 0;
background: yellow;
/* to occupy remaining space */
flex: 1 1 auto;
/* for columns inside to occupy full width */
display: flex;
flex-flow: row wrap;
/* for immediate children to stretch to max height possible */
align-items: stretch;
}
.col1, .col2, .col3 {
float: left;
/* to occupy remaining width */
flex: 1 0 auto;
}
.colPadding {
padding: 25px;
background: blue;
}
.cb {
width: 100%;
height: 1px;
clear: both;
}
/* Custom CSS */
/* style to apply when the screen is less than or equal to 300px (you can change this to 768px) */
#media screen and ( max-height: 300px ){
body {
height: 100vh; /* for body to have a size of the full screen */
}
header {
margin: 0px; /* remove margin bottom */
}
section {
padding: 0px; /* remove margin bottom and top/bottom padding */
margin: 0px;
}
}
More on CSS3 flex-box here.

Setting div 100% of window without content overflowing

I am trying to set up my page layout to take up 100% of the screen but am running into problems with content overflowing into the footer.
Here's the code for the first example:
HTML:
<div class="container page-container">
<div class="page-leftSidebar">
<div class="sidebar" role="complementary">
<h4>Widget Title</h4>
</div>
<main class="post-wrapper" role="main">
<section class="entry-content">
<p>This makes the entire page 100% height, but <code>.post-wrapper</code> is not for some reason.</p>
</section>
</main>
</div>
</div>
<footer class="siteFooter">
<p>Copyright 2015 Me.</p>
</footer>
CSS:
/* Generic */
html,
body { height: 100%; }
body {
background-color: #f3f3f3;
margin: 0;
padding: 0;
}
/* Containers */
.container {
margin: 0 auto;
width: 90%;
}
.page-container { min-height: 100%; }
/* Page Content */
.post-wrapper {
background-color: #fff;
min-height: 100%;
}
/* This is the row that will hold our two columns (sidebar and content) */
.page-leftSidebar {
width: 100%;
min-height: 100%;
}
.page-leftSidebar:after {
clear: both;
content:" ";
display: table;
}
.page-leftSidebar .sidebar { -webkit-background-clip: padding-box; }
#media (min-width: 60em) {
/* Page container */
.page-leftSidebar .post-wrapper {
-webkit-background-clip: padding-box;
min-height: 100%;
}
/* Left Sidebar */
.page-leftSidebar .sidebar {
float: left;
width: 19.25%;
}
/* Right Content */
.page-leftSidebar .post-wrapper {
float: left;
margin-left: 2%;
width: 78.75%;
}
}
/* Site Footer */
.siteFooter {
background-color: #2b303b;
color: #555555;
text-align: center;
padding-bottom: 50px;
padding-top: 50px;
}
/* FULL PAGE HEIGHT */
.container { min-height: 100%; }
.post-wrapper,
.page-leftSidebar,
.sidebar {
display: block;
position: relative;
height: 100%;
}
I got things kind of working here, but my .post-wrapper container is still not 100% height: http://jsfiddle.net/1re4vLq4/10/
However, the above example does work if there is a lot of content on the page: http://jsfiddle.net/1re4vLq4/9/ (Note: that both this and the above example are using min-height)
Then I got the entire page (including .post-wrapper) to be 100% height by using height instead of min-height: http://jsfiddle.net/9m1krxuv/4/
Changed CSS:
.container { height: 100%; }
.post-wrapper,
.page-leftSidebar,
.sidebar {
display: block;
position: relative;
height: 100%;
}
However, the problem with this is when there is a lot of content on the page, it overflows onto the footer (you can see this by making the result pane in JSFiddle smaller): http://jsfiddle.net/1re4vLq4/8/ Which shouldn't be the case (nor do I want to hide the text using overflow: hidden).
Any suggestions or ideas on how to go about fixing this? I'm looking for the entire page to be at least 100% height, including .post-wrapper (which is the right column with a white background).
If you have a "full-sized" container that you want to always match the height of the viewport - you're best not to add content that will overflow (go beyond) that div, as you're essentially defeating the purpose.
Short answer: Remove height: 100%; from your .container CSS rule.
I've created a basic Fiddle example combining full-viewport-height divs, and divs that just hold a lot of content.
HTML:
<div class="full-div red height-full">
<!-- Full sized div. Content should fit within the viewport -->
</div>
<div class="full-div blue">
<div class="inner-div">
<!-- Add long lorem ipsum here. -->
<!-- Notice that the parent div does not contain the height-full class -->
</div>
</div>
<div class="full-div green height-full">
<!-- This div will get "pushed down"only because the div above is NOT height 100% -->
</div>
CSS:
html,body{ height: 100%; margin: 0; padding: 0; }
.full-div { overflow: auto; }
.height-full { height: 100%; }
.inner-div { width: 90%; background-color: white; margin: 0 auto; }
.inner-div span { text-align: center; }
DEMO here: http://jsfiddle.net/175mrgzt/
Ultimately, when you set a DIV to 100% - its expected to be 100% of the viewport (graphical viewing region of the browser). Once you add content that extends that you're essentially going over 100% - and in that case, you might as well remove the set height, and let HTML make the adjustments for you.

Make 3 column divs responsive. Help me spot what I'm doing wrong?

The div elements inside the row are floated left, as described here:
http://www.w3schools.com/html/html_responsive.asp
and percentage sized.
I tried to apply what was suggested in this link below, in a similar question, but without success:
Responsive CSS / Inline divs
The divs keep an inline relation of 50% - 100% - 50% and their contents overlap.
Can anyone help me spot what I missed?
Thank you.
In my CSS and HTML I have:
footer[role="contentinfo"] div {
box-sizing: border-box;
}
.engage-row:after {
content: "";
display: table;
clear: both;
}
.col-1 {
float: left;
width: 25%;
}
.col-2 {
float: left;
width: 50%;
padding: 10px 20px 0px 20px;
}
.col-3 {
float: left;
width: 25%;
}
.footer-wfix {
clear: both;
}
/* for illustrative purposes */
.engage-row {
border: 1px solid red;
}
.engage-row > div {
border: 1px solid blue;
}
<footer id="colophon" role="contentinfo">
<div class="footer-wrap">
<div class="engage-row">
<div class="col-1">
Column 1
</div>
<div class="col-2">
Column 2
</div>
<div class="col-3">
Column 3
</div>
</div>
<div class="footer-wfix">
Footer Menu and Site-generator
</div>
</div>
</footer><!-- #colophon -->
Edited the code and am adding the below for clarity:
- I edited the footer by adding the "engage-row" and it's containing column divs.
- All divs have inherited box-sizing: border-box.
- Column 1, Column 2 and Column 3 don't readjust positioning when I decrease the screen size (width); instead of becoming on top of each others, they are changing their size (keeping percentages but becoming smaller), making the containing text and images overlap (text from column 2 goes in front of the image in column 1). I hope I am using the correct terms for clarity.
- How can I make them readjust the positioning as the screen size changes?
- PrintScreen: 3column divs in footer
(This is an awesome site. Thank you)
You need to take into account the padding in the .col-2 declaration. When you have three columns adding up to a total of "100 % width" and then add padding, the result so to speak is "more than 100 % width", causing the overlapping behavior you observe.
One way around it is to declare the paddings in percent as well. If you don't like the resulting "elastic margins", you need to figure out a equation that works. Or check out Bootstrap or something similar (I mean you can either use it as is, or decipher their responsive solutions).
You need to add the css3 property box-sizing: border-box; This will wrap your padding into your div, so the width will be 50% only.
Please share your feedback if its helpful for your problem.
.col-2{
float: left;
width: 50%;
padding:10px 20px 0px 20px;box-sizing: border-box;
}
you mention 25% 50% 25% and a border of div so overlapped,
in this case use box-sizing: border-box;
.engage-row:after {
content: "";
display: table;
clear: both;
}
.col-1 {
float: left;
width: 25%;
}
.col-2 {
float: left;
width: 50%;
padding: 10px 20px 0px 20px;
}
.col-3 {
float: left;
width: 25%;
}
.footer-wfix {
clear: both;
}
/* for illustrative purposes */
.engage-row {
border: 1px solid red;
}
.engage-row > div {
border: 1px solid blue;
box-sizing: border-box;/*added one*/
}
This is what I needed (I couldn't be clear until I researched enough):
The left and right divs include images and I didn't want those to change size as I decrease the screen resolution. I wanted to input that adjustment in the middle div which contains only text and a subscription form.
The question/answer that drove me there:
How to make element fill remaining width, when sibling has variable width?
My testing fiddle - http://jsfiddle.net/0gvxxpjj/
<!-- In html--->
<div class="row">
<div class="col-1">
<img src="">
</div>
<div class="col-3">
<img src="">
</div>
<div class="col-2">
<h3>Header</h3>
<p>This is a paragraph that, along with the header, needs to wrap as the screen is resized</p>
</div>
</div>
<!-- html ends here-->
/* CSS starts here */
.col-1 {
float: left;
width: 100px;
}
.col-3 {
float: right;
width: 100px;
}
.col-2{
padding: 10px 20px 0px 20px;
overflow: hidden;
}
.row {
border: 1px solid black;
display: inline-block;
}
.col-1, .col-3 {
border: 1px solid blue;
}
.col-2 {
border: 1px dashed red;
}
Hope it becomes useful to someone else.
As I understand it, you want to have the divs be in a 25% - 50% - 25% layout and after the browser shrinks beyond a certain size, they become 100% width and stack on top of each other.
This is done via media queries. What, essentially, happens is that you set some CSS rules inside a media query which adds to any previous CSS rules only when a certain condition has been met (in this case browser width). A rough example can be seen below.
These are the relevant parts:
This sets how the divs will look by default - full width.
.col-1,
.col-2,
.col-3 {
float: left;
width: 100%;
}
This sets the widths of the divs to 25-50-25 once the browser width is larger than 768px.
#media all and (min-width:768px) {
.col-1, .col-3 {
width: 25%;
}
.col-2 {
width: 50%;
}
}
You can extend this example to the layout you desire.
footer[role="contentinfo"] div {
box-sizing: border-box;
}
.engage-row:after {
content: "";
display: table;
clear: both;
}
.col-1,
.col-2,
.col-3 {
float: left;
width: 100%;
}
.col-2 {
padding: 10px 20px 0px 20px;
}
.footer-wfix {
clear: both;
}
/* for illustrative purposes */
.engage-row {
border: 1px solid red;
}
.engage-row > div {
border: 1px solid blue;
}
#media all and (min-width:768px) {
.col-1, .col-3 {
width: 25%;
}
.col-2 {
width: 50%;
}
}
<footer id="colophon" role="contentinfo">
<div class="footer-wrap">
<div class="engage-row">
<div class="col-1">
Column 1
</div>
<div class="col-2">
Column 2
</div>
<div class="col-3">
Column 3
</div>
</div>
<div class="footer-wfix">
Footer Menu and Site-generator
</div>
</div>
</footer><!-- #colophon -->

How to make a fluid grid with fixed width columns?

I guess I have the simplest problem ever and cannot find a ready solution.
I need to make a grid of square items with fixed widths and heights and fixed distance between them.
I need three columns maximum, and during browser resizing I would need this grid to shrink to two, and then one column (items must always keep their size and distance between them).
That's why I don't like any open source grid system (Boostrap, Skeleton, etc.) they all use %width, and columns always change width on resizing.
What would be the simplest way?
Just a random simple mock-up for a page with a bunch of squares, resize result at will:
http://jsfiddle.net/cuAfg/
HTML:
<div class="container">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
/* etc */
</div>
CSS:
.container {
width: 960px;
margin: auto;
overflow: auto;
}
#media only screen and (max-width : 960px) {
.container {
width: 640px;
}
}
#media only screen and (max-width : 640px) {
.container {
width: 320px;
}
}
.block {
width: 300px;
height: 300px;
float:left;
margin: 10px;
background: #ccc;
}
if your blocks have a known width and horizontal margins, you can set a maw-width on parent container to allow maximum 3 of them per lines.
For instance, a 200px square boxe with 40px margin around, 900px of width would allow 3 of them, the fourth will go down.
Once it shrinks, only 2 are left and so on.
Demos with float, inline-block or flex .You may set a min-width too if you like.
Method used does not really matters here :) .
CODEPEN
html,
<div class="container">
<div class="inner-container">
<div class="box">a</div>
<div class="box">b</div>
<div class="box">c</div>
</div>
</div>
and the css,
* {
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box;
text-align: center;
}
.container {
/* width = 200 * 3 + 25 * 2 = 650 */
float: left;
position: relative;
left: 50%;
}
.inner-container {
float:left;
position: relative;
left: -50%;
}
.container::after {
content: '';
display: block;
clear: both
}
.box {
float: left;
background-color: blue;
width: 200px;
height: 200px;
margin-right: 25px;
margin-bottom: 25px;
display: inline-block
}
.box:last-child {
margin-right: 0
}
this way, a b and c will retain its original width and height. When the container does not have sufficient width, c will go down, then b.
There are a couple of techniques. Since your question is vague I can only cover them in general terms.
First you start with a fixed with:
width: <number>px;
Then to create columns you can do:
display: inline-block;
Or
float: left;
If you go with floats you may need to overflow: auto on the main container so the main layout doesn't collapse.