CSS - Centered div fill remaining horizontal space - html

Please, I am learning CSS by my self and have 2 questions:
I have 3 DIV inside a "top" DIV, and I need the second (in the center) to fill all the remaining space.
Where is what I got: https://fiddle.jshell.net/3j838det/
Here is the HTML code:
<div class="main">
<div class="top">
<div class="first">1</div>
<div class="second">2</div>
<div class="third">3</div>
</div>
<div class="bottom">bottom</div>
</div>
Here is the CSS code:
.main {
width: 500px;
margin: 10px auto 0 auto;
border: 1px solid #000000;
}
.main .top {
border-bottom: 1px solid #000000;
background-color: #CDCDCD;
}
.main .top .first {
width: 140px;
padding: 4px;
display: inline-block;
background-color: #FFCC66;
}
.main .top .second {
width:auto;
padding: 4px;
display: inline-block;
background-color: #FF9966;
}
.main .top .third {
width: 100px;
padding: 4px;
display: inline-block;
background-color: #FF6666;
}
.main .bottom{
height:60px;
padding: 4px;
}
My questions are:
How can I make second DIV to fill all the remaining space?
Why there is a space between first and second DIV, and between second and third DIV, if I did not define any margin?
Thank you!!

How can I make second DIV to fill all the remaining space?
A job for Flexbox! :D
Add the following CSS:
.main .top {
display: -webkit-flex;
display: flex;
}
.main .top .second {
-webkit-flex: 1;
flex: 1;
}
Why there is a space between first and second DIV, and between second and third DIV, if I did not define any margin?
Because there are spaces between the divs in the markup (line break + indentation), and because you display the divs as inline-blocks.
See also How to remove the space between inline-block elements?.
Flexbox eliminates this problem though, so you can remove display: inline-block at once.
[ Updated fiddle ]

Use the table-cell layout.
.main {
width: 500px;
margin: 10px auto 0 auto;
border: 1px solid #000000;
}
.main .top {
width: 100%;
border-bottom: 1px solid #000000;
background-color: #CDCDCD;
display: table;
table-layout: fixed;
}
.main .top .first {
display: table-cell;
width: 140px;
padding: 4px;
background-color: #FFCC66;
}
.main .top .second {
display: table-cell;
padding: 4px;
background-color: #FF9966;
}
.main .top .third {
display: table-cell;
width: 100px;
padding: 4px;
background-color: #FF6666;
}
.main .bottom {
height:60px;
padding: 4px;
}

How can I make second DIV to fill all the remaining space?
You can calculate the width of the .second class by calculating the remaining width available with calc. Like so:
width: calc(100% - 264px);
The 264 above was calculated from the total width from first and third divs (140px + 100px = 240px) plus the total padding for all elements (24px), which is = 264px.
Why there is a space between first and second DIV, and between second and third DIV, if I did not define any margin?
You're having gaps because of how inline-block works. It's like the spaces between between words. There are a few ways to solve this, but float: left should do here. Like so:
float: left;
Also add width: 100% to your top element and set it to display: inline-block.
Try this Demo
.main {
width: 500px;
margin: 10px auto 0 auto;
border: 1px solid #000000;
}
.main .top {
border-bottom: 1px solid #000000;
background-color: #CDCDCD;
display: inline-block;
width: 100%;
}
.main .top > div {
padding: 4px;
float: left;
}
.main .top .first {
width: 140px;
background-color: #FFCC66;
}
.main .top .second {
width: calc(100% - 264px);
background-color: #FF9966;
}
.main .top .third {
width: 100px;
background-color: #FF6666;
}
.main .bottom{
clear: both;
height:60px;
padding: 4px;
}
<div class="main">
<div class="top">
<div class="first">1</div>
<div class="second">2</div>
<div class="third">3</div>
</div>
<div class="bottom">bottom</div>
</div>

There are two standard ways to achieve this.
display: table;
* {
box-sizing: border-box;
}
.main {
width: 500px;
margin: 10px auto 0 auto;
border: 1px solid #000000;
}
.top {
display: table;
width: 100%;
border-bottom: 1px solid #000000;
background-color: #CDCDCD;
}
.cell {
display: table-cell;
width: 60px;
padding: 4px;
}
.first {
background-color: #FFCC66;
}
.second {
width: 100%;
background-color: #FF9966;
}
.third {
background-color: #FF6666;
}
.bottom {
height: 60px;
padding: 4px;
}
<div class="main">
<div class="top">
<div class="cell first">1</div>
<div class="cell second">2</div>
<div class="cell third">3</div>
</div>
<div class="bottom">bottom</div>
</div>
overflow: hidden;
* {
box-sizing: border-box;
}
.main {
width: 500px;
margin: 10px auto 0 auto;
border: 1px solid #000000;
}
.top {
border-bottom: 1px solid #000000;
background-color: #CDCDCD;
}
.top:after {
content: '';
clear: both;
display: block;
}
.top .first {
float: left;
width: 140px;
padding: 4px;
background-color: #FFCC66;
}
.top .second {
overflow: hidden;
padding: 4px;
background-color: #FF9966;
}
.top .third {
float: right;
width: 100px;
padding: 4px;
background-color: #FF6666;
}
.main .bottom {
height: 60px;
padding: 4px;
}
<div class="main">
<div class="top">
<div class="first">1</div>
<div class="third">3</div>
<div class="second">2</div>
</div>
<div class="bottom">bottom</div>
</div>

Inline-block elements alway take some space (depend on it's font size) to it's right side. So better way to use flex. But you can use this css below to solve them right now.
.main .top>div{
margin-right: -4px;
}

Related

Responsive layout with four floating divs

How do I achieve a responsive layout in my code?
I have four divs with different heights. The layout for the smaller screen is as expected.
For the larger screen, I want to float the second (blue) and forth (brown) divs to the left and the first (red) and third (green) divs to the right, as shown in the image.
Here is my code:
CSS
.wrapper {
border: 2px solid;
padding: 10px;
min-height: 300px;
}
.first-div {
border: 2px solid red;
height: 80px;
margin-bottom: 10px;
}
.second-div {
border: 2px solid blue;
height: 200px;
margin-bottom: 10px;
}
.third-div {
border: 2px solid green;
height: 180px;
margin-bottom: 10px;
}
.forth-div {
border: 2px solid brown;
height: 100px;
}
#media (min-width: 892px) {
.first-div {
float: right;
width: 500px;
}
.second-div {
float: left;
width: 280px;
}
.third-div {
clear: both;
float: right;
width: 500px;
}
.forth-div {
clear: both;
float: left;
width: 280px;
}
}
h4 {
text-align: center;
}
.clear-both {
clear: both;
}
HTML
<div class="wrapper">
<div class="first-div"><h4>First Div</h4></div>
<div class="second-div"><h4>Second Div</h4></div>
<div class="third-div"><h4>Third Div</h4></div>
<div class="forth-div"><h4>Forth Div</h4></div>
<div class="clear-both"></div>
</div>
You just need to make a few changes in your code. Firstly, you need to change the order of your DIV's (what DIV comes first, which one comes after that etc).
Secondly, you need to remove few of the float and clear properties from your CSS. I have attached a runnable code snippet below, with a few changes in your code: (just be sure to view the results in "full page" view, or else it would show the results of smaller screens).
.wrapper {
border: 2px solid;
padding: 10px;
min-height: 300px;
}
.first-div {
border: 2px solid red;
height: 80px;
margin-bottom: 10px;
}
.second-div {
border: 2px solid blue;
height: 200px;
margin-bottom: 10px;
}
.third-div {
border: 2px solid green;
height: 180px;
margin-bottom: 10px;
}
.forth-div {
border: 2px solid brown;
height: 100px;
}
#media (min-width: 892px) {
.first-div {
float: right;
width: 500px;
clear: right;
}
.second-div {
width: 280px;
clear: left;
}
.third-div {
clear: right;
float: right;
width: 500px;
}
.forth-div {
float: left;
width: 280px;
clear: left;
}
}
h4 {
text-align: center;
}
.clear-both {
clear: both;
}
<!DOCTYPE html>
<html>
<body>
<div class="wrapper">
<div class="first-div">
<h4>First Div</h4>
</div>
<div class="third-div">
<h4>Third Div</h4>
</div>
<div class="second-div">
<h4>Second Div</h4>
</div>
<div class="forth-div">
<h4>Forth Div</h4>
</div>
<div class="clear-both"></div>
</div>
</body>
</html>
I advise the solution to flex. I arranged the blocks as you need on the desktop version. Also, I removed <div class="clear-both"></div>. Because it is enough to make the free space by specifying the width: 90%. At a screen width of 892px, a media query is triggered.
Blocks become responsive!
Hope you like it.
.wrapper {
border: 2px solid;
padding: 10px;
min-height: 300px;
}
.container {
display: flex;
flex-flow: wrap;
flex-direction: column;
gap: 10px;
width: 90%;
height: 300px;
}
.container div {
box-sizing: border-box;
width: calc((100% / 2) - (10px / 2));
flex: 1 0 auto;
}
.first-div {
border: 2px solid red;
height: 80px;
order: 3;
}
.second-div {
border: 2px solid blue;
height: 200px;
order: 1;
}
.third-div {
border: 2px solid green;
height: 180px;
order: 4;
}
.forth-div {
border: 2px solid brown;
height: 80px;
order: 2;
}
h4 {
text-align: center;
}
#media (max-width: 892px) {
.container {
width: 100%;
height: auto;
}
.container div {
width: 100%;
order: unset;
}
}
<div class="wrapper">
<div class="container">
<div class="first-div"><h4>First Div</h4></div>
<div class="second-div"><h4>Second Div</h4></div>
<div class="third-div"><h4>Third Div</h4></div>
<div class="forth-div"><h4>Forth Div</h4></div>
</div>
</div>
Here is the fixed version, I hope this is what you wanted. I altered your html a bit, as you can see, css as well, but it's pretty clear what is going on in my code, if you have any questions, ask away !
Just a tip :
Dont use float property, it's very bad and deprecated, use flex or css grid for responsive design ! :)
.wrapper {
border: 2px solid;
padding: 10px;
min-height: 300px;
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
.secondForth{
width : 40%;
}
.firstThird{
width : 40%;
}
.allFour{
display: none;
}
.first-div {
border: 2px solid red;
height: 80px;
margin-bottom: 10px;
}
.second-div {
border: 2px solid blue;
height: 200px;
margin-bottom: 10px;
}
.third-div {
border: 2px solid green;
height: 180px;
margin-bottom: 10px;
}
.forth-div {
border: 2px solid brown;
height: 100px;
}
#media (max-width: 892px) {
.secondForth, .firstThird{
display: none;
}
.allFour{
display: block;
width: 100%;
}
}
h4 {
text-align: center;
}
<div class="wrapper">
<div class="secondForth">
<div class="second-div"><h4>Second Div</h4></div>
<div class="forth-div"><h4>Forth Div</h4></div>
</div>
<div class="allFour">
<div class="first-div"><h4>First Div</h4></div>
<div class="second-div"><h4>Second Div</h4></div>
<div class="third-div"><h4>Third Div</h4></div>
<div class="forth-div"><h4>Forth Div</h4></div>
</div>
<div class="firstThird">
<div class="first-div"><h4>First Div</h4></div>
<div class="third-div"><h4>Third Div</h4></div>
</div>
</div>

Aligning three divs side by side in a single row

I'm looking to align three divs side by side without any flexbox and grid.
This is the style that I'm looking for: Image
This is what I'm currently getting: Image
.container {
width: 600px;
border: 1px solid black;
}
.box-1 {
width: 180px;
height: 100px;
background: grey;
margin: 10px;
display: inline-block;
}
.box-2 {
width: 180px;
height: 100px;
background: grey;
margin: 10px;
display: inline-block;
}
.box-3 {
width: 180px;
height: 100px;
background: grey;
margin: 10px;
display: inline-block;
}
<div class="container">
<div class="box-1"></div>
<div class="box-2"></div>
<div class="box-3"></div>
</div>
Note: Just asking about alignment, not the border, background etc
Edit: The parent container has width 600px. It cannot be changed. And the children have 180px width and 100px height, and margin of 10px.
You can resolve it using display: flex; layout on .container class.
The default direction of flex layout is row (flex-direction: row).
.container {
width: 600px;
border: 1px solid black;
display: flex;
}
.box-1 {
width: 180px;
height: 100px;
background: grey;
margin: 10px;
display: inline-block;
}
.box-2 {
width: 180px;
height: 100px;
background: grey;
margin: 10px;
display: inline-block;
}
.box-3 {
width: 180px;
height: 100px;
background: grey;
margin: 10px;
display: inline-block;
}
<div class="container">
<div class="box-1"></div>
<div class="box-2"></div>
<div class="box-3"></div>
</div>
Hey increase the width of the container as follow:
.container {
width: 1000px;
border: 1px solid black;
}
.box-1 {
width: 180px;
height: 100px;
background: grey;
margin: 10px;
display: inline-block;
}
.box-2 {
width: 180px;
height: 100px;
background: grey;
margin: 10px;
display: inline-block;
}
.box-3 {
width: 180px;
height: 100px;
background: grey;
margin: 10px;
display: inline-block;
}
<div class="container">
<div class="box-1"></div>
<div class="box-2"></div>
<div class="box-3"></div>
</div>
or use display : flex in your container both will help....
If you dont want to use Flexbox, You can simply try increasing the width such that all 3 divs are aligned in a single line
like Aahad said...

How to center inline-block element with margin

HTML:
<div id="wrap">
<div id="block1"></div>
<div id="block2"></div>
</div>
CSS:
div#wrap{
margin-top: 3em;
border: solid 1px black;
text-align: center;
}
div#wrap *{
display: inline-block;
width: 12.5em;
margin-top: 1em;
height: 8em;
}
div#wrap *:not(:last-child){
margin-right: 8em;
}
#block1{
background: orange;
}
div#wrap #block2{
background: magenta;
}
These 2 blocks are supposed to be centered in responsive design mode. When the screen is wide enough to have 2 blocks in a row, the code works. But when I narrow the screen down, the top block is shifted to the left because of the margin:
fiddle
Is it possible to fix this without media queries?
Edit
I tried flex-box:
div#wrap{
margin-top: 3em;
border: solid 1px black;
display: flex;
flex-flow: row wrap;
justify-content: center;
}
fiddle2
A solution is to use flex and justify-content:space-around and remove margin:
div#wrap {
margin-top: 3em;
border: solid 1px black;
justify-content:space-around;
display: flex;
flex-wrap: wrap;
}
div#wrap * {
display: inline-block;
width: 12.5em;
margin-top: 1em;
height: 8em;
}
#block1 {
background: orange;
}
#block2 {
background: magenta;
}
<div id="wrap">
<div id="block1"></div>
<div id="block2"></div>
</div>
If you use a container with negative margin, you don't need to vary the margin for the endpoints of the rows at different breakpoints and you can just go with inline-block. I set font-size to zero in the container so I can calculate my widths using percents without worrying about white space.
div#wrap {
margin-top: 3em;
border: solid 1px black;
padding: 20px;
text-align: center;
}
.block {
display: inline-block;
width: 12.5em;
margin: 20px;
height: 8em;
font-size: 16px;
}
.block-container {
margin: -20px;
font-size: 0;
}
#block1 {
background: orange;
}
#block2 {
background: magenta;
}
<div id="wrap">
<div class="block-container">
<div class="block" id="block1"></div>
<div class="block" id="block2"></div>
</div>
</div>

Centered container with text on the left and squared image on the right?

I'm losing my mind here over something that seems to be very simple, but after playing around for several hours I thought it was time to ask for some help.
What I need is a container (see pink colour) that is centered on the page and is 70% of the page it's width. Then there should be two Divs inside of the container.
One of the left for text, and one on the right for a square image that should stay at a fixed size (Let's say 200x200px - I mean, it looks so weird to end up having a 50x50px avatar next to a block of text after scaling your browser down). It's OK if the right Div shifts below the first Div on mobile devices.
I haven't been able to find a useful answer on here, but I've been playing around with the code below (which does the opposite - small (image) block on the left) but for some reason I just can't get it to work.
.wrapper {
border: 2px solid #000;
overflow: hidden;
}
.wrapper div {
min-height: 200px;
padding: 10px;
}
#one {
background-color: gray;
float: left;
margin-right: 20px;
width: 140px;
border-right: 2px solid #000;
}
#two {
background-color: white;
overflow: hidden;
margin: 10px;
border: 2px dashed #ccc;
min-height: 170px;
}
#media screen and (max-width: 400px) {
#one {
float: none;
margin-right: 0;
width: auto;
border: 0;
border-bottom: 2px solid #000;
}
}
<div class="wrapper">
<div id="one">one</div>
<div id="two">two</div>
</div>
Any help would be highly appreciated!
Image with what I mean
You could use flexbox
.wrapper {
display: flex;
width: 70%;
max-width: 1000px; /* added this to limit its width on very wide screens */
margin: 0 auto;
border: 2px solid #000;
overflow: hidden;
}
.wrapper div {
min-height: 200px;
padding: 10px;
}
#one {
flex: 1;
background-color: gray;
border-right: 2px solid #000;
}
#two {
margin: 10px;
border: 2px dashed #ccc;
width: 200px;
}
#media screen and (max-width: 600px) {
.wrapper {
flex-direction: column;
}
#one {
border-right: none;
}
#two {
width: auto;
}
}
<div class="wrapper">
<div id="one">one</div>
<div id="two">two</div>
</div>
Another option for wide screens would be an additional media query
.wrapper {
display: flex;
width: 70%;
margin: 0 auto;
border: 2px solid #000;
overflow: hidden;
}
.wrapper div {
min-height: 200px;
padding: 10px;
}
#one {
flex: 1;
background-color: gray;
border-right: 2px solid #000;
}
#two {
margin: 10px;
border: 2px dashed #ccc;
width: 200px;
}
#media screen and (max-width: 600px) {
.wrapper {
flex-direction: column;
}
#one {
border-right: none;
}
#two {
width: auto;
}
}
#media screen and (min-width: 1200px) {
.wrapper {
width: 50%;
}
}
<div class="wrapper">
<div id="one">one</div>
<div id="two">two</div>
</div>

Flexbox: Move header and footer to sidebar with flexbox

My content layout consists of three sections: header, content and footer. For small devices I want to keep this order, on desktop I would like to move header and footer to the sidebar.
Implemented using floats: http://codepen.io/anon/pen/jqrZby
Markup
<div class="page">
<div class="top"></div>
<div class="content"></div>
<div class="bottom"></div>
</div>
CSS
.page {
border: 2px solid black;
padding: 1em;
}
.page:after {
content: "";
display: block;
clear: both;
}
.page > * {
margin-bottom: 1em;
}
.top {
border: 2px solid red;
height: 100px;
}
.content {
border: 2px solid blue;
height: 400px;
}
.bottom {
border: 2px solid green;
height: 200px;
}
#media screen and (min-width: 800px) {
.content {
width: 66%;
float: left;
}
.top, .bottom {
width: 33%;
float: right;
}
}
I'm trying to find a solution using flexbox with a fixed spacing between content and sidebar. Anybody got an idea if this is possible?
Without changing the stucture and using flexbox you need to use flex-direction:column.
First we build it "mobile first" because it follows the actual order of the div structure we have already.
Then, at the appropriate media query we need to make the container wrap...often this will require a fixed height (be it viewport or px value)...then we can re-order the elements (using, ahem, order) and impose our required widths.
Codepen Demo
* {
box-sizing: border-box;
}
.page {
border: 2px solid black;
display: flex;
flex-direction: column;
height: 400px;
padding: 1em;
}
.top {
border: 2px solid red;
height: 100px;
width: 100%;
order: 1;
margin-bottom: 1em;
}
.content {
border: 2px solid blue;
height: 400px;
order: 2;
}
.bottom {
border: 2px solid green;
height: 200px;
order: 3;
margin-top: 1em;
}
#media screen and (max-width: 800px) {
.page {
flex-wrap: wrap;
justify-content: space-between;
}
.top {
order: 2;
}
.top,
.bottom {
width: 33%;
}
.content {
order: 1;
flex: 0 0 100%;
width: 66%;
margin-right: 1em;
}
}
<div class="page">
<div class="top">top</div>
<div class="content">content</div>
<div class="bottom">bottom</div>
</div>