Setting layout with flexbox - css

I have a wireframe below and want to see what's the best way to code this with flexbox.
I have coded a simple flexbox grid system but my wireframe requires more customization than what I have on my grid system.
I have parent div has display: flex and have 2 child divs have flex:1 and flex: 0 0 40%.
What is the best way to add content div(gray boxes inside on blue and red) that will stay with rest of main wrapper(entire gray box sets to max-width: 1400px)?
Thank you.

Here's the general idea.
Positioned pseudo-elements, one for each section of the row. With a suitable width (note that the body should have overflow-x:hidden) and appropriate positioning values.
* {
box-sizing: border-box;
}
body {
overflow-x: hidden;
}
.wrapper {
min-height: 100vh; /* for demo purposes */
width: 60%;
margin: auto;
background: grey;
display: flex;
flex-direction: column;
}
header {
height: 20vh;
background: green;
}
.inner {
height: 30vh;
display: flex;
}
main {
background: blue;
flex: 1;
border: 2px solid black;
}
aside {
background: red;
flex: 0 0 40%;
border: 2px solid black;
}
.other {
background: pink;
flex: 1;
}
/* magic section */
.extend {
position: relative;
}
.extend::after {
content: '';
position: absolute;
width: 100vw;
top: 0;
height: 100%;
background: inherit;
z-index: -1;
}
.left::after {
right: 0;
}
.right::after {
left: 0;
}
<div class="wrapper">
<header></header>
<div class="inner">
<main class="extend left"></main>
<aside class="extend right"></aside>
</div>
<div class="other"></div>
</div>

Related

How to have 2 overlapping elements fill their parent

I need 2 elements (in the demo marked #a and #b) to both fill their parent entirely. I need element #a filling it's parent (this is easy, I just set flex to 1), and I need element #b to be atop of #a and have exactly same size as #a. How to make #b have the same size? If I set width/height to 100% #b will overflow.
body {
margin: 0;
display: flex;
width: 100vw;
height: 100vh;
}
nav {
background-color: silver;
}
main {
flex: 1;
border: 5px solid green;
display: flex;
}
#a {
border: 1px solid aqua;
flex: 1;
}
#b {
position: absolute;
border: 1px dashed blue;
flex: 1;
}
<nav>sidebar of variable width</nav>
<main>
<div id="a">aaa</div>
<div id="b">bbb</div>
</main>
If you set the parent (main) to position: relative while #b is position: absolute then you should be able to size it in relation to main (100% width and height in this case) and position it to top and left 0.
body {
margin: 0;
display: flex;
width: 100vw;
height: 100vh;
}
nav {
background-color: silver;
}
main {
flex: 1;
border: 5px solid green;
display: flex;
position: relative;
}
#a {
border: 1px solid aqua;
flex: 1;
}
#b {
position: absolute;
border: 1px dashed blue;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<nav>sidebar of variable width</nav>
<main>
<div id="a">aaa</div>
<div id="b">bbb</div>
</main>

Overlapping two boxes

I have been trying to have two boxes in CSS, one in the upper right hand corner of the other. I have been trying to nest divs and use relative positioning but I cannot figure out how to do it. Can someone help me? (Not using z index)
If I understand correctly that you want one box to be inside the other, you can achieve this using position: relative and moving the inner box using top, right, left and bottom.
I recommend diving in to the MDN page for CSS position for more information.
.box1, .box2 {
display: inline-block;
}
.box1 {
width: 200px;
height: 200px;
background: green;
}
.box2 {
position: relative;
width: 100px;
height: 100px;
top: -100px;
left: -100px;
background: orange;
}
<div class='box1'></div>
<div class='box2'></div>
You can use something like this. Using flexBox to align them and giving a negative margin to second box.
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
min-height: 100vh;
margin: 0;
background-color: bisque;
display: grid;
place-content: center;
}
.container{
display: flex;
flex-direction: row;
}
.first{
height: 5rem;
width: 5rem;
background-color: tomato;
}
.second{
margin-top:-50%;
height: 5rem;
width: 5rem;
background-color: tomato;
}
<div class="container">
<div class="first"></div>
<div class="second"></div>
</div>
Based on Marcos answer i think i understand you wrong.
Here is a simple way get the result that you want. You can use position:relative to parent and position: absolute to child item. Then you can move child element inside. top:0; will take you to top corner and right:0; will take you to right corner.
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
min-height: 100vh;
margin: 0;
background-color: bisque;
display: grid;
place-content: center;
}
.parent{
width: 10rem;
height: 10rem;
background-color: tomato;
position: relative;
}
.child {
width: 5rem;
height: 5rem;
background-color: aqua;
position: absolute;
top:0;
right: 0;
}
<div class="parent">
<div class="child"></div>
</div>
Spontaneously, I can think of two possibilities. 1) Work with 'position' or 2) work with 'margin'.
here an example with margin in combination flexbox;
.w {
background-color: lightgray;
display: flex;
justify-content: center;
padding: 20px;
}
.a, .b {
width: 150px;
height: 150px;
}
.a {
background-color: lightblue;
}
.b {
background-color: lightgreen;
margin-top: 20px;
margin-left: -20px;
}
<div class="w">
<div class="a">A</div>
<div class="b">B</div>
</div>

How to make background height 100% of the parent's height

I'm trying to create a menu inside CSS, and this is how my HTML skeleton looks like:
<body>
<div class="menu-container">
<ul class="menu-list">
<li class="menu-item">Item1</li>
<li class="menu-item">Item2</li>
<li class="menu-item">Item3</li>
</ul>
</div>
</body>
This is the part of CSS I'm focusing on:
.menu-container {
background-color: #e5e5e5;
width: 100%;
height: 4rem;
position: fixed;
bottom: 0;
display: flex;
align-items: center;
}
.menu-list {
margin: 0 auto;
}
.menu-item {
display: inline-block;
}
.menu-item:not(:last-child) {
margin-right: 5vw;
}
.menu-item:hover {
background-color: red;
}
Basically, what I'm trying to achieve is setting the background color of each element to red, on element hover (<li>). The problem is, the background color seems not to fill the whole height of its parent (the menu-container), although this is what I actually want to do.
I tried setting the menu-item padding to 100%, but it just fills the whole screen. It isn't relative to menu-container's height.
To be more precise, this is how it looks like:
But I want the red background's height all over the div, like this:
What can I do, in order to achieve that? Thank you.
So, Instead of giving a fixed height to parent div. I adjust this using by adding padding from the top and bottom to each lielement.
Made some changes on CSS Have a look the snippet below:
.menu-container {
background-color: #e5e5e5;
width: 100%;
position: fixed;
bottom: 0;
display: flex;
align-items: center;
}
.menu-list {
margin: 0 auto;
}
.menu-item {
display: inline-block;
padding: 1.25rem 0;
}
.menu-item:not(:last-child) {
margin-right: 5vw;
}
.menu-item:hover {
background-color: red;
}
<body>
<div class="menu-container">
<ul class="menu-list">
<li class="menu-item">Item1</li>
<li class="menu-item">Item2</li>
<li class="menu-item">Item3</li>
</ul>
</div>
</body>
Just add height:100% to both menu-list and menu-item. In case you want the item to be centered instead of sticking to the top you can use a display: flex and align-items: center, justify-content:center
.menu-container {
background-color: blue;
width: 100%;
height: 4rem;
position: fixed;
bottom: 0;
display: flex;
align-items: center;
justify-content:center;
}
.menu-list {
height: 100%;
background-color:yellow;
display:flex;
align-items: center;
justify-content:center;
}
.menu-item {
display: flex;
align-items:center;
justify-content:center;
height:100%;
background-color:green;
}
.menu-item:not(:last-child) {
margin-right: 5vw;
}
.menu-item:hover {
background-color: red;
}
You can make your CSS like this,
Giving the height to 100% will take 100% height of the parent element.
I am trying to fix your css, please check my solution -
.menu-container {
background-color: #e5e5e5;
width: 100%;
height: 4rem;
position: fixed;
bottom: 0;
display: flex;
align-items: center;
}
/* at first you inline the whole ul */
.menu-list {
margin: 0 auto;
display: flex;
list-style: none;
}
/* then center the options & set full height */
.menu-item {
display: flex;
align-items: center;
height: 4rem;
cursor: pointer;
padding: 0 1rem;
}
.menu-item:not(:last-child) {
margin-right: 5vw;
}
.menu-item:hover {
background-color: red;
}
Solution 2
.menu-container {
background-color: #e5e5e5;
width: 100%;
position: fixed;
bottom: 0;
display: flex;
align-items: center;
}
/* set full height */
.menu-list {
margin: 0 auto;
height: 100%;
}
/* set full height also */
.menu-item {
display: inline-block;
padding: 1.25rem 0;
height: 100%;
}
.menu-item:not(:last-child) {
margin-right: 5vw;
}
.menu-item:hover {
background-color: red;
}

Firefox not ignoring fixed position elements when outside container width

I wasn't sure of the best way to explain this, but if you look at the example snippet in Chrome or Safari, the orange div does not cause the document to scroll horizontally when the window is narrower than the blue container. This is the desired behavior.
However, in Firefox, if you make the window narrow it counts the orange box as content that needs to be able to be scrolled to, causing the document to scroll to the right in an odd way that shifts the body content to the left and is ugly. What's also strange is that you'll notice the green box on the left DOESN'T cause it to have scrollable space to the left...is this a bug, or why is this happening?
Anyone else encountered this?
* {
box-sizing: border-box;
}
.wrapper {
max-width: 700px;
height: 200px;
margin: 0 auto;
}
.banner {
width: 100%;
height: 100%;
padding: 10px;
background-color: blue;
position: relative;
transform: scale(1);
color: #ffffff;
}
.banner:before, .banner:after {
content: '';
width: 100px;
height: 100%;
position: fixed;
left: -100px;
top: 0;
background-color: green;
}
.banner:after {
left: 100%;
background-color: orange;
}
.content {
width: 100%;
height: 300px;
padding: 10px;
background-color: #f1f1f1;
margin-top: 40px;
}
<div class="wrapper">
<div class="banner">Banner</div>
<div class="content">Content</div>
</div>
You can wrap that in an element that will scale with the viewport and set overflow: hidden on that element. You can also remove the transform: scale() from .banner and use position: absolute on the pseudo elements, unless scale(1) is needed for some reason.
* {
box-sizing: border-box;
}
header {
overflow: hidden;
}
.wrapper {
max-width: 700px;
height: 200px;
margin: 0 auto;
}
.banner {
height: 100%;
padding: 10px;
background-color: blue;
position: relative;
color: #ffffff;
}
.banner:before, .banner:after {
content: '';
width: 100px;
height: 100%;
position: absolute;
left: -100px;
top: 0;
background-color: green;
}
.banner:after {
left: 100%;
background-color: orange;
}
.content {
height: 300px;
padding: 10px;
background-color: #f1f1f1;
margin-top: 40px;
}
<header>
<div class="wrapper">
<div class="banner">Banner</div>
<div class="content">Content</div>
</div>
</header>

Fit divs vertically on a parent div with fixed height and width

I have a layout wherein the container has a fixed height and width of 640px x 480px. Inside this container are 3 divs, top, mid and bot. I want this 3 divs to fit inside the container provided that they will not overflow the container. The top and bot div doesn't have fixed height while the mid should fit the space between and push top and bot.
What I've already tried was like this:
HTML
<div class="main">
<div class="top">
</div>
<div class="mid">
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/Chestnut-breasted_Malkoha2.jpg/593px-Chestnut-breasted_Malkoha2.jpg" />
</div>
<div class="bot">
</div>
</div>
CSS
.main {
padding: 10px;
width: 640px;
height: 480px;
display: inline-block;
background: #000;
position: relative;
}
.top {
width: 100%;
height: 50px;
display: block;
background: #eee;
}
.mid {
width: 100%;
height: 100%;
display: block;
background: #333;
}
img {
max-width: 100%;
max-height: 100%;
margin: 0 auto;
display: block;
}
.bot {
width: 100%;
height: 50px;
display: block;
background: #ccc;
}
FIDDLE HERE
Now my problem is the mid push the bot outside the container. How can i make them fit inside the container without using overflow: hidden? Thanks in advance.
NOTE : the image should fit inside the mid container.
UPDATE top and bot div can contain paragraphs so it's not fixed height.
Check this sample:
http://jsfiddle.net/J6QTg/8/
.main {
padding: 50px 0px;
width: 640px;
height: 480px;
display: block;
background: #000;
position: relative;
box-sizing: border-box;
-moz-box-sizing: border-box;
}
.top {
width: 100%;
height: 50px;
display: block;
background: #eee;
position: absolute;
top : 0;
left : 0;
}
.mid {
width: 100%;
height: 100%;
display: block;
background: #333;
}
img {
max-width: 100%;
max-height: 100%;
margin: 0 auto;
display: block;
}
.bot {
width: 100%;
height: 50px;
display: block;
background: #ccc;
position: absolute;
bottom : 0;
left : 0;
}
Update:
It is also possible to use tables, to have more flexible boxes.
http://jsfiddle.net/jslayer/U3EaZ/
HTML:
<div class="box">
<div class="h"> Hello<br/>Cruel<br/>World </div>
<div class="m">
<img src="http://goo.gl/a1smCR" alt="" />
</div>
<div class="b"> Omg </div>
</div>
CSS:
.box {
display: table;
width: 640px;
height: 480px;
background: red;
}
.h, .m, .b {
display: table-row;
}
.h {
background: yellow;
height: 0;
}
.m {
background: green;
}
.m img {
max-width: 100%;
height: 100%;
max-height: 100%;
margin: 0 auto;
display: block;
}
.b {
background: blue;
height: 0;
}
I would use JavaScript/JQuery: FIDDLE
I've used JQuery for simplicity, but it can probably be done with just JavaScript...
var totalheight = eval($('.main').height() - $('.top').outerHeight(true) - $('.bot').outerHeight(true))
$('.mid').outerHeight(totalheight);
Try to set the height of mid based on the container.
.mid {
width: 100%;
height: 383px;
display: block;
background: #333;
}
FIDDLE
If the container has a fixed height and width, then you can set the height to 79.25% like this:
.mid {
max-width: 100%;
height: 79.25%;
display: block;
background: #333;
}
demo

Resources