I try to make a grid of four boxes each 50% height and 50% width of the full screen size, like shown in this picture:
http://a.pomf.se/gqnzzs.jpg
My problem is that I can't get the 50% height to work. How can I set the height of 2 div above each other at each a height of 50% of the viewport size?
HTML:
<div class="wrapper">
<div class="row">
<div class="panel-1">... </div>
<div class="panel-2">...</div>
</div>
<div class="row">
<div class="panel-3">...</div>
<div class="panel-4">...</div>
</div>
</div>
CSS:
.wrapper{
width: 100%;
height: 100%;
display: inline-block;}
.panel-1{
width: 50%;
float: left;
height: 50%;}
.panel-2{
width: 50%;
float: left;
height: 50%;}
.panel-3{
width: 50%;
float: left;
height: 50%;}
.panel-4{
width: 50%;
float: left;
height: 50%;}
I greatly appreciate any help!
Greets
In supported browsers, you can use viewport-percentages units, vh, vw, vmin, vmax.
In this case, just use 50vh, where 1 unit equals 1% of the height of the initial containing block.
Example Here
.panel-1, .panel-2,
.panel-3, .panel-4 {
height: 50vh;
width: 50%;
float: left;
}
For what it's worth, if you want to still use percentage based units, you would need to define all the parent element's heights too:
Updated Example
html, body, .wrapper {
height: 100%;
}
.row {
height: 50%;
}
.panel-1, .panel-2,
.panel-3, .panel-4 {
height: 100%;
width: 50%;
float: left;
}
Solved by flexbox. Caniuse
No float, no clearfixes - simple and clear;
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html,
body {
padding: 0;
margin: 0;
height: 100%;
}
body {
background-color: #333;
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -ms-flexbox;
display: box;
display: flex;
-webkit-box-flex: 1;
-moz-box-flex: 1;
-o-box-flex: 1;
box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
-o-box-orient: horizontal;
-webkit-box-lines: multiple;
-moz-box-lines: multiple;
-o-box-lines: multiple;
-webkit-flex-flow: row wrap;
-ms-flex-flow: row wrap;
flex-flow: row wrap;
}
.flex__item {
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -ms-flexbox;
display: box;
display: flex;
-webkit-box-flex: 1;
-moz-box-flex: 1;
-o-box-flex: 1;
box-flex: 1;
-webkit-flex: 0 0 50%;
-ms-flex: 0 0 50%;
flex: 0 0 50%;
height: 50%;
background-color: #777;
border: 1px solid #000;
}
.flex__item:nth-child(1) {
background-color: #9aa0a8;
}
.flex__item:nth-child(2) {
background-color: #a7c4b5;
}
.flex__item:nth-child(3) {
background-color: #a9d8b8;
}
.flex__item:nth-child(4) {
background-color: #beffc7;
}
<div class="flex__item"></div>
<div class="flex__item"></div>
<div class="flex__item"></div>
<div class="flex__item"></div>
You need to set following:
html { height:100%; width:100%;}
body { width:100%;height:100%;}
Then "div" will work with "height:50%".
Related
I am creating a website and trying to get the best css setup (responsive/works on all browsers) for creating a section where an image is either right or left of a block of text. I heard that flex was the best way to go, so I tried mimicking other websites that use a flex setup. So far I have a chunk of code that works for when the image is to the right, and the text is to the left....but it doesn't work for when image is to the left, and the text is to the right.
Here's my code: https://codepen.io/7harrypotterrr/pen/MZEdVY
.containerabcolumn {margin: 0 auto !important;}
As you can see, when I reverse the orders of div a and b, the results are bad. On my actual site, there's actually no overlap, but theres an issue with how the image overflows. When the window size is shrunk down for the first section of code, things works as intended...the image to the right goes beyond its div container and cuts off more and more as the window size is shrunk (that's good)....however for the second section of code where the image is to the left and text right, the image ends up overlapping the text...instead of going beyond its container to the left (the way I want it to).
Any ideas how to fix?
Thanks in advance for any help I get, and as you can tell from the way I tried to describe my issue, I am a complete noob at coding.
Also, if anyone have thoughts as to whether this set of code is responsive/works on all browsers/generally a smart approach, that would be great too.
You ask for the right approach so I will give two answers. Answer 1 answers your request. Answer 2 is a more elegant and professional solution that - with the same css - is able to display two views, optimized depending on the target screen
Solution 1: respecting your intention also on mobile
in order to have both the problems solved
this fix the text over the image, as per the other answer:
.b img {
width: 100%;
}
removing flex: 0 0 auto; makes fixes the text cut on mobile:
.a {
-webkit-flex-basis: 41.667%;
-ms-flex-preferred-size: 41.667%;
flex-basis: 41.667%;
max-width: 50%;
margin: auto;
}
This is a simulation on a Pixel2 XL after the two css modifications
Solution 2: best UX
The preceding solution mimics the dynamics of a desktop screen. But on a mobile you want to see better the text and the image. This doesn't happen with the preceding solution. So my suggestion is to go with this css. You will preserve the same layout you want on desktop screens BUT you will reorganize the things much better when you open the page on mobile
<style>
.containerabc {
background-color: #fff;
display: block;
overflow: hidden;
width: 100%;
}
.containerabcolumn {
margin: 0 auto !important;
max-width: 1080px;
float: none !important;
position: static !important;
}
.containerabc .et_pb_text {
box-sizing: border-box;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin-right: -0.5rem;
margin-left: -0.5rem;
}
.a {
-webkit-flex-basis: 41.667%;
-ms-flex-preferred-size: 41.667%;
flex-basis: 41.667%;
max-width: 50%;
margin: auto;
}
.b {
-webkit-flex-basis: 58.333%;
-ms-flex-preferred-size: 58.333%;
flex-basis: 58.333%;
max-width: 50%;
box-sizing: border-box;
-webkit-box-flex: 0;
-webkit-flex: 0 0 auto;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
flex-basis: auto;
flex-basis: auto;
padding-right: 0.5rem;
padding-left: 0.5rem;
}
.b img {
width: 100%;
}
#media only screen and (max-width: 600px)
{
.containerabc .et_pb_text
{
display: block;
}
.a
{
margin: unset;
max-width: 100%;
padding: 20px;
}
.b
{
max-width: 100%;
padding: 20px;
}
}
</style>
Desktop behavior
Mobile behavior
Update after OP clarification
.containerabc {
background-color: #fff;
display: block;
overflow: hidden;
width: 100%;
}
.containerabcolumn {
margin: 0 auto !important;
max-width: 1080px;
float: none !important;
position: static !important;
}
.containerabc .et_pb_text {
box-sizing: border-box;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin-right: -0.5rem;
margin-left: -0.5rem;
}
.a {
-webkit-flex-basis: 41.667%;
-ms-flex-preferred-size: 41.667%;
flex-basis: 41.667%;
max-width: 50%;
margin: auto;
display: inline-block;
position: relative;
top: 0px;
left: 50px;
padding-left: 30px;
padding-right: 30px;
padding-top: 100px;
padding-bottom: 150px;
background: white;
}
.b {
-webkit-flex-basis: 58.333%;
-ms-flex-preferred-size: 58.333%;
flex-basis: 58.333%;
max-width: 50%;
box-sizing: border-box;
-webkit-box-flex: 0;
-webkit-flex: 0 0 auto;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
flex-basis: auto;
flex-basis: auto;
padding-right: 0.5rem;
padding-left: 0.5rem;
}
.b img {
width: 100%;
min-width: 700px;
position: relative;
overflow: hidden;
}
#media only screen and (max-width: 600px)
{
.containerabc .et_pb_text
{
display: block;
}
.a
{
margin: unset;
max-width: 100%;
padding: 20px;
position: unset;
}
.b
{
max-width: 100%;
padding: 20px;
}
.b img
{
width: 100%;
min-width: unset;
}
}
You simply need to define 'width: 100%;' to your image inside div. Something like:
.b img {
max-width: 700px;
width: 100%;
}
How do I stretch the divs with a yellow background to full height? It should cover up the green but it is not working. I tried adding height: 100% on it but then it adds up the height from the search bar?
https://jsfiddle.net/nuy20j1h/
.block {
width: 80%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}
.sidebar {
height: 600px;
width: 25%;
background: red;
}
.home {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
width: 75%;
background: green;
}
.search-bar {
width: 100%;
padding: 25px;
background: blue;
}
.content-wrap {
display: flex;
flex-wrap: wrap;
width: 100%;
align-items: flex-stretch;
}
.content,
.single {
width: 50%;
background: yellow;
}
<div class="block">
<div class="sidebar">sidebar</div>
<div class="home">
<div class="search-bar">search bar</div>
<div class="content-wrap">
<div class="content">lorem ipsum</div>
<div class="single">test</div>
</div>
</div>
</div>
First you should add a style reset, I'm using this now * {} as you can se below. The trick here is to run flex-direction: column; on .home and you can tell .content-wrap to take up the rest of that space after the search with flex-grow: 1;
box-sizing: border-box; is, if you add let's say width: 200px; to a element, and add padding: 20px;, the element will stay 200px with the padding included. If you don't have that, it will take up 200px + 40px.
if you want the fiddle, here it is
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.block {
width: 80%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}
.sidebar {
height: 600px;
width: 25%;
background: red;
}
.home {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: flex-start;
width: 75%;
background: green;
}
.search-bar {
width: 100%;
padding: 25px;
background: blue;
}
.content-wrap {
display: flex;
flex-grow: 1;
flex-wrap: wrap;
width: 100%;
align-items: flex-stretch;
}
.content,
.single {
width: 50%;
background: yellow;
}
<div class="block">
<div class="sidebar">sidebar</div>
<div class="home">
<div class="search-bar">search bar</div>
<div class="content-wrap">
<div class="content">lorem ipsum</div>
<div class="single">test</div>
</div>
</div>
</div>
As mentioned in other answers, there is one main issue here:
flex-direction: column;, which I added to home, to enable the usage of flex properties instead of height, to make the .content-wrap fill the available space left in home
That will make the .search-bar and .content-wrap stack vertical, and enable the use of flex: 1 on .content-wrap, which will make it fill the remaining space/height.
So even if you got answers already, and since there are some properties with wrong value, or not needed, I decided to post an answer to clarify the changes made.
See my notes made in the CSS for further clarifications and what I changed.
Stack snippet
.block {
width: 80%;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}
.sidebar {
height: 600px;
width: 25%;
background: red;
}
.home {
display: flex;
flex-direction: column; /* added */
/*flex-wrap: wrap; removed, not needed */
/*align-items: flex-start; removed, items should fill parent's,
in this changed case, width */
width: 75%;
background: green;
}
.search-bar {
/*width: 100%; not needed, default for column
item is to fill parent width as
its "align-items" is "stretch" */
padding: 25px;
background: blue;
}
.content-wrap {
flex: 1; /* added, take the remaining space left
left of its parent (height in this case) */
display: flex;
flex-wrap: wrap;
/*width: 100%; not needed, default for column
item is to fill parent width as
its "align-items" is "stretch" */
/*align-items: flex-stretch; wrong value, should be "stretch",
though since that is the default,
it is not needed */
}
.content,
.single {
width: 50%;
background: yellow;
}
<div class="block">
<div class="sidebar">sidebar</div>
<div class="home">
<div class="search-bar">search bar</div>
<div class="content-wrap">
<div class="content">lorem ipsum</div>
<div class="single">test</div>
</div>
</div>
</div>
flex-direction: column; is your friend. Here is a reworked fiddle of your code: https://jsfiddle.net/vsjktmms/1/
Using the same HTML structure you provided:
.block {
display: flex;
width: 80%;
margin: 0 auto;
background-color: gray;
align-items: stretch;
}
.sidebar {
width: 25%;
height: 600px;
background-color: red;
}
.home {
display: flex;
flex-direction: column;
align-items: stretch;
width: 75%;
background-color: green;
}
.search-bar {
padding: 25px;
background-color: blue;
}
.content-wrap {
flex: 1 1 auto;
display: flex;
flex-wrap: wrap;
width: 100%;
background-color: pink;
}
.content,
.single {
width: 50%;
background: yellow;
}
I have three sections in a container. When I resize my browser to the max-width of 668px, I need to make the section 1 and section 3 in one row and the section 2 in the below row. The section 2 width should be proportional to the section 1 and section 3 width.
But now once I minimize the browser size to 668px and below, then section 3 is not visible.
This is what I tried.
#media (max-width: 668px) {
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-self: flex-start;
}
.container .section1 {
height: 300px;
}
.container .section1,
.container .section3 {
flex: 0 0 262px;
margin: 3px;
display: block;
flex-grow: 0;
flex-shrink: 0;
}
.container .section2 {
flex: 0 0 500px;
flex-grow: 0;
flex-shrink: 0;
order: 1;
min-height: 235px;
}
}
#media (max-width: 940px) {
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-self: flex-start;
}
.container .section1 {
height: 300px;
}
.container .section1,
.container .section3 {
flex: 0 0 262px;
margin: 3px;
display: block;
flex-grow: 0;
flex-shrink: 0;
}
.container .section2 {
flex: 0 0 500px;
flex-grow: 0;
flex-shrink: 0;
order: 1;
min-height: 235px;
}
}
<div class="container">
<div class="section1">Section 1</div>
<div class="section2">Section 2</div>
<div class="section3">Section 3</div>
</div>
You don't have any height specified on .section3.
On .section1 you have height: 300px.
On .section2 you have min-height: 235px.
But on .section3 you have nothing. Try this adjustment to your code:
.section1, .section3 {
height: 300px;
}
jsFiddle demo
I have a problem in chrome which does not happen in Firefox.
<div class="container">
<div class="flex-1"></div>
<div class="flex-2">
<div class="flex-2-child"></div>
<div class="flex-3-child"></div>
</div>
</div>
.container {
height: 200px;
width: 500px;
display: -moz-box;
display: -webkit-flexbox;
display: -ms-flexbox;
display: -webkit-flex;
display: -moz-flex;
display: flex;
-webkit-flex-direction: row;
-moz-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
}
.flex-1 {
width: 100px;
background-color: blue;
}
.flex-2 {
position: relative;
-moz-box-flex: 1;
-webkit-flex: 1;
-moz-flex: 1;
-ms-flex: 1;
flex: 1;
background-color: red;
}
.flex-2-child {
height: 100%;
width: 100%;
background-color: green;
}
.flex-3-child {
height: 100%;
width: 100%;
background-color: steelblue;
}
http://jsfiddle.net/michaelch/TfB9c/2/
If you check this fiddle in firefox and in chrome, you will see there is a big difference.
flex-2-child and flex-3-child have no height in chrome, but have the behavior which i think is right which both have a 100% height relative to their parent.
Do you know how to have the correct behavior in chrome?
Thanks in advance.
Michael
You will get the same result in Chrome as you do in Firefox if you add height: 100%; to your .flex-2 class.
.flex-2 {
position: relative;
-moz-box-flex: 1;
-webkit-flex: 1;
-moz-flex: 1;
-ms-flex: 1;
flex: 1;
background-color: red;
height: 100%; // Add this!
}
If a child's height is defined by a percentage of their parent's height, then the parent's height should be defined.
I'm trying to achieve a responsive Layout with:
- A fixed header width width 100% and an height of e.g. 50px
- 3 equal squares on the right, taking over the whole space from the top to the bottom of the page.
- A main content are taking over the remaining space on the page
Currently my code looks like this (jsfiddle) but I can't get the width of the boxes on the right to be set automatically based on the current height in order to be displayed as squares... Does anybody know a solution for this in pure CSS?
HTML:
<div id="mainView">
<div id="content">
</div><!-- content -->
<div id="squaressWrapper">
<div id="square1"></div><!-- dummy -->
<div id="square2"></div><!-- dummy -->
<div id="square3"></div><!-- dummy -->
<div id="square4"></div><!-- dummy -->
</div><!-- squaressWrapper -->
</div><!-- mainView -->
</div><!-- wrapper -->
CSS:
html {
height: 100%;
margin: 0;
padding: 0;
}
body {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px;
}
#wrapper {
width: 100%;
height: 100%;
display: flex;
display: -webkit-flex;
flex-direction: column;
-webkit-flex-direction: column;
-webkit-align-content: stretch;
align-content: stretch;
}
#header {
height: 50px;
width: 100%;
background: #ffb8c4;
}
#mainView {
flex: 1;
-webkit-flex: 1;
position: relative;
background: #666;
}
#squaressWrapper {
position: absolute;
height: 100%;
background: green;
right: 0;
display: flex;
display: -webkit-flex;
flex-direction: column;
-webkit-flex-direction: column;
-webkit-align-content: stretch;
align-content: stretch;
}
#square1 {
position: relative;
flex: 1;
-webkit-flex: 1;
width: 100px;
border: 2px solid white;
background: green;
}
#square2 {
position: relative;
flex: 1;
-webkit-flex: 1;
width: 100px;
border: 2px solid white;
background: green;
}
#square3 {
position: relative;
flex: 1;
-webkit-flex: 1;
width: 100px;
border: 2px solid white;
background: green;
}
I get a solution, using vh units as suggested by Nicho.
The CSS
#squaressWrapper {
position: absolute;
height: 100%;
width: 33vh;
right: 0;
display: flex;
display: -webkit-flex;
flex-direction: column;
-webkit-flex-direction: column;
-webkit-align-content: stretch;
align-content: stretch;
}
.squares {
position: relative;
flex: 1;
-webkit-flex: 1;
width: calc(100% - 15px);
border: 2px solid white;
background: green;
right: -11px;
}
demo
The dimensions are a little bit strange because setting the width of the container to calc(33vh - 15px) didn't work.
May be in a near future that will be easier.
I don't know what is the browser support for this, I tested it only in Chrome.
Note : 15px is the dimension of the header (45px) divided by the number of squares.
Well I took a shot at this...
I changed your sizes up on your css
here is the link to the fiddle.
http://jsfiddle.net/D7RSP/2/
#header {
height: 20%;
width: 100%;
background: #ffb8c4;
}
#mainView {
flex: 1;
width: 69%;
height: 100%;
float: left;
background: green;
}
.square {
flex: 1;
-webkit-flex: 1;
width: 30%;
border: 1px solid white;
background: green;
height: 25%;
float:right;
}