I made a simple example to test this out. I have one wrapper div with two other div elements inside it set to display: inline-block;. The two inner div elements fall on the same line, but how do I get them centered on the half of the main div they belong to? For example, the blue box in the middle of the left side of the main div and the red box in the middle of the right side of the main div. Code and screenshot below.
Also, the inspector shows a width of 204px for the main-box div and even when I set padding and margin to 0 there's still a gap on the bottom between the blue/red boxes and the border of the main-box. How do I get rid of the gap?
.box-test {
height: 200px;
display: inline-block;
width: 30%;
box-sizing: border-box;
}
#blue {
background-color: blue;
}
#red {
background-color: red;
}
#main-box {
text-align: center;
border: 1px solid black;
}
<div id="main-box">
<div id="blue" class="box-test"></div>
<div id="red" class="box-test"></div>
</div>
Use flexbox and margin:auto on both elements and they will get centred like you want and you will also get rid of all the whitespace issues:
.box-test {
height: 200px;
margin:auto;
width: 30%;
box-sizing: border-box;
}
#blue {
background-color: blue;
}
#red {
background-color: red;
}
#main-box {
border: 1px solid black;
display:flex;
}
<div id="main-box">
<div id="blue" class="box-test"></div>
<div id="red" class="box-test"></div>
</div>
What you should use is a flexbox for the wrapper. When defining space-around for the 'horizontal alignment' you will get what you want.
For more details on flexbox see here
* {
box-sizing: border-box;
}
#main-box {
border: 1px solid black;
display: flex;
justify-content: space-around;
}
.box-test {
height: 200px;
width: 30%;
}
#blue {
background-color: blue;
}
#red {
background-color: red;
}
<div id="main-box">
<div id="blue" class="box-test"></div>
<div id="red" class="box-test"></div>
</div>
You can use flexbox with property justify-content: space-around on the wrapper.
.box-test {
height: 200px;
width: 30%;
}
#blue {
background-color: blue;
}
#red {
background-color: red;
}
#main-box {
display: flex;
justify-content: space-around;
border: 1px solid black;
}
<div id="main-box">
<div id="blue" class="box-test"></div>
<div id="red" class="box-test"></div>
</div>
#main-box {
text-align: center;
border: 1px solid black;
font-size:0;
}
Why it is so?
Please read this:
https://css-tricks.com/fighting-the-space-between-inline-block-elements/
Removing whitespace between HTML elements when using line breaks
https://jsfiddle.net/evzckd3w/
Related
I would like the button to be positioned at the bottom right of the red colored div. I used padding-bottom and margin-bottom properties but that does not seem to work. Could anyone please help?
.container {
display: flex;
flex-direction: column;
width: 300px;
height: 200px;
border: 1px solid blue;
padding: 8px;
}
.box {
width: 300px;
height: 150px;
border: 1px solid red;
}
.button {
float: right;
}
<div class="container">
<div class="box">
</div>
<div>
<button class="button">Click</button>
</div>
</div>
.button {
float: right;
position:relative;
transform:translate(-5px,-25px); //x and y controls
}
I have just answered the same thing to other question. ... Use position:relative. I see the point why people refrain from using it. But really ain't no shame. Especially when there isn't a parent-child relation between the elements.
.container {
display: flex;
flex-direction: column;
width: 300px;
height: 200px;
border: 1px solid blue;
padding: 8px;
}
.box {
width: 300px;
height: 150px;
border: 1px solid red;
}
.button {
float: right;
position:relative;
top: -22px;
}
<div class="container">
<div class="box">
</div>
<div>
<button class="button">Click</button>
</div>
</div>
An alternative to the other answers using display: grid instead. This is easier for the browser than using position absolute or float!!
/* ignore */ body { margin: 0 } * { box-sizing: border-box } /* ignore */
.container {
display: grid;
width: 50vw;
height: 100vh;
border: 1px solid blue;
padding: 8px;
}
.box, .button { grid-area: 1/1/-1/-1 }
.box { border: 1px solid red }
.button { margin: auto 0 0 auto }
<div class="container">
<div class="box">
</div>
<div class="button">
<button>Click</button>
</div>
</div>
I want .board element to have a square aspect ratio. I want to show two of them side by side, together covering the width of their parent.
I don't want to use width: 50%, because I want to position .wrap element with display: flex.
.board {
position: relative;
background: red;
width: 100%;
height: 0;
padding-bottom: 100%;
border: 1px solid black;
}
.wrap {
display: flex;
}
<div class="wrap">
<div class="board"></div>
<div class="board"></div>
</div>
When I do it like this, I get two divs with squashed width.
Use aspect-ratio and flex:1
.board {
position: relative;
background: red;
flex:1;
aspect-ratio:1/1;
border: 1px solid black;
}
.wrap {
display: flex;
}
<div class="wrap">
<div class="board"></div>
<div class="board"></div>
</div>
Alternatively flex:1 and padding-bottom:50%;
.board {
position: relative;
background: red;
flex: 1;
padding-bottom: 50%;
border: 1px solid black;
}
.wrap {
display: flex;
}
<div class="wrap">
<div class="board"></div>
<div class="board"></div>
</div>
Is there a way I can make the blue div wrap text once it butts up against the yellow div instead of stacking on top of the yellow one? Is there a way I can use overflow or wordwrap? that will make this work?
blue div to wrap once it butts up against yellow div
.container {
width:100%;
border: px solid #d3d3d3;
}
.container div {}
.wrap1 {
display: table;
border: 1px solid green;
width: 100%;
}
.wrap2 {
display: table;
border: 1px solid red;
width: 100%;
}
.title {border: 1px solid blue;
display: table;
float: left;
}
.container .learn {
float: right;border: 1px solid yellow;
cursor: pointer;
display: table;
}
.container .content {
display: table;
display: none;
padding: 5px;
}
<div class="container">
<div class="wrap1">
<div class="title">How do we shop our carriers to find you the best price when we have so many?</div>
<div class="learn">Learn More!</div>
</div>
<!--makes the content expand below this div-->
<div class="wrap2">
<div class="content">
<p> We use what is called a Comparative Rater. We simply input your information
which then gets sent out to all the carriers and within a minute they return their
prices. From there we choose the best one for you similar to shopping online for
flights and hotels.</p>
</div>
</div>
<!--holds the content below the wrap one div-->
</div>
<!--container-->
Use flexbox!
Add display: flex; to your containers. This will wrap your text once it reaches the other div. I've included a snippet example that should work for you.
.container {
width:100%;
border: px solid #d3d3d3;
}
.container div {}
.wrap1 {
display: flex;
justify-content: space-between;
border: 1px solid green;
width: 100%;
}
.wrap2 {
display: table;
border: 1px solid red;
width: 100%;
}
.title {border: 1px solid blue;
display: table;
float: left;
}
.container .learn {
float: right;border: 1px solid yellow;
cursor: pointer;
display: table;
}
.container .content {
display: table;
display: none;
padding: 5px;
}
<div class="container">
<div class="wrap1">
<div class="title">How do we shop our carriers to find you the best price when we have so many?</div>
<div class="learn">Learn More!</div>
</div>
<!--makes the content expand below this div-->
<div class="wrap2">
<div class="content">
<p> We use what is called a Comparative Rater. We simply input your information
which then gets sent out to all the carriers and within a minute they return their
prices. From there we choose the best one for you similar to shopping online for
flights and hotels.</p>
</div>
</div>
<!--holds the content below the wrap one div-->
</div>
<!--container-->
You could put display: flex; onto the wrap1 class instead of display table and I believe this will get the effect you are wanting.
Set a percentage width on the div and then use word-wrap: break-word;
.container {
width:100%;
border: px solid #d3d3d3;
}
.container div {}
.wrap1 {
display: table;
border: 1px solid green;
width: 100%;
}
.wrap2 {
display: table;
border: 1px solid red;
width: 100%;
}
.title {border: 1px solid blue;
display: table;
float: left;
word-wrap: break-word;
width: 50%;
}
.container .learn {
float: right;border: 1px solid yellow;
cursor: pointer;
display: table;
}
.container .content {
display: table;
display: none;
padding: 5px;
}
<div class="container">
<div class="wrap1">
<div class="title">How do we shop our carriers to find yfkasjldkfjl;kjsdfl;kjsdfasdfasdfou the best price when we have so many?</div>
<div class="learn">Learn More!</div>
</div>
<!--makes the content expand below this div-->
<div class="wrap2">
<div class="content">
<p> We use what is called a Comparative Rater. We simply input your information
which then gets sent out to all the carriers and within a minute they return their
prices. From there we choose the best one for you similar to shopping online for
flights and hotels.</p>
</div>
</div>
<!--holds the content below the wrap one div-->
</div>
<!--container-->
Flexbox can do that.
.container {
width: 60%; /* for demo */
margin:auto;
border: 1px solid #d3d3d3;
}
.container div {}
.wrap1 {
display: flex;
border: 1px solid green;
}
.title {
flex: 1;
border: 1px solid blue
}
.container .learn {
border: 1px solid yellow;
cursor: pointer;
}
<div class="container">
<div class="wrap1">
<div class="title">How do we shop our carriers to find you the best price when we have so many?</div>
<div class="learn">Learn More!</div>
</div>
</div>
<!--container-->
If you want a really clean solution, I'd recommend using flex-box! Elements defined within the flex boxed container will have to share the given width amongst themselves based on their needs (how much content is within them).
I like adding a min-width to the small element so it doesn't get squashed.
.container {
width:100%;
border: 5px solid #d3d3d3;
}
.wrap1 {
border: 1px solid green;
width: 100%;
display: flex;
flex-direction: row;
}
.wrap2 {
border: 1px solid red;
width: 100%;
}
.title {
border: 1px solid blue;
}
.learn {
min-width: 25%;
border: 1px solid yellow;
cursor: pointer;
}
I would suggest staying away from floats as much as possible. It takes the element out of it's traditional flow and can cause other problems when styling.Another solution is to use display: inline-block - if child elements don't take up the full width of their parent's container, they will share the space. A bit wonky with 75%/24%, which is why I prefer flex-box.
.container {
width:100%;
border: 5px solid #d3d3d3;
box-sizing: content-block;
}
.wrap1 {
border: 1px solid green;
width: 100%;
}
.wrap2 {
border: 1px solid red;
width: 100%;
}
.title {
border: 1px solid blue;
max-width: 75%;
display: inline-block;
}
.learn {
display: inline-block;
width: 24%;
border: 1px solid yellow;
cursor: pointer;
}
How to vertical-align without using display table/table-cell or position absolute ?
#parent {
border: 1px solid red;
height: 100vh;
}
.child {
border: 1px solid blue;
}
<div id="parent">
<div class="child">
<p>I want to be vertical aligned</p>
</div>
</div>
Here is an another option using "Flex" property.
<div id="parent">
<div class="child">
<p>I want to be vertical aligned</p>
</div>
</div>
#parent {
border: 1px solid red;
display: flex;
align-items: center;
height: 100vh;
}
.child {
border: 1px solid blue;
flex-grow: 1;
}
Codepen demo link
You can use position relative, with top of 50% and a translation of -50%.
#parent {
border: 1px solid red;
height: 100vh;
}
.child {
position: relative;
top: 50%;
transform: translate(0,-50%);
border: 1px solid blue;
}
<div id="parent">
<div class="child">
<p>I want to be vertical aligned</p>
</div>
</div>
Another method could be to use a floater div
#parent {
border: 1px solid red;
height: 100vh;
}
.floater {
float:left;
height:50%;
width:100%;
margin-bottom: -25px;
}
.child {
border: 1px solid blue;
clear: both;
height:50px;
}
<div id="parent">
<div class="floater"></div>
<div class="child">
<p>I want to be vertical aligned</p>
</div>
</div>
You can try using display:flex.
CSS
#parent {
border: 1px solid red;
height: 100vh;
display: flex;
align-items: center; /* vertical */
justify-content: center; /* horizontal */
}
.child {
border: 1px solid blue;
}
<div id="parent">
<div class="child">
<p>I want to be vertical aligned</p>
</div>
</div>
You can use display:flex;:
#parent {
border: 1px solid red;
height: 100vh;
display:flex;
align-items:center;
justify-content:center;
}
You can use like that I think
position: fixed; top: 50%;
if you do not mind browser compatibility I would go with flex - see #rblarsen, #Satheesh Kumars answers.
but if you need to expand browser support, here is a more complex but rather solid solution : tested IE9+ FF Chrome and other major browsers...
check out this fiddle : https://jsfiddle.net/kLLz0nm2/
HTML
<div class="wrapper">
<div class="content">Middle aligned</div>
<div class="middle"></div>
</div>
CSS
.wrapper{
width : 100%;
height : 100%;
text-align: center;
}
.content{
display: inline-block;
vertical-align: middle;
}
.middle{
height: 100%;
display: inline-block;
vertical-align: middle;
}
P.S - the above translate solution while fairly simple can sometimes cause poor rendering issues, check out :
I am attempting to create a full-width banner with three internal inline elements. A back link, a logo and a forward link.
I would also like to use the same code to create a full-width banner with TWO internal inline elements. A left back link and a central logo.
What I have so far, is:
HTML
<section id="header-blue">
<div id="header-wrap">
<div class="header-left"><p>1</p></div>
<div class="header-center"><p>2</p><p>2</p><p>2</p><p>2</p></div>
<div class="header-right"><p>3</p><p>3</p></div>
<div class="clearfix"></div>
</div>
</section>
SCSS:
#header-blue {
width: 100%;
margin-bottom: 50px;
height: auto;
background-color: $primary-blue;
color: #fff;
#header-wrap {
text-align: center;
border: 1px solid green;
margin: 0 auto;
padding: 1rem 2.5rem;
div {
display: inline-block;
vertical-align: middle;
}
}
.header-left {
float: left;
border: 1px solid red;
width: 100px;
}
.header-right {
float: right;
border: 1px solid red;
width: 100px;
}
.header-center {
border: 1px solid red;
margin: 0 auto !important;
display: inline-block;
width: 100px;
}
} // header-blue
I am looking for a solution that is widely supported, so I'm not sure if that rules flex out?
The result is this: FIDDLE
EDIT:
THE FINAL CORRECT DESIGN WHEN COMPLETE
Disclaimer: Please understand that although this may be viewed as a 'duplicate' post, after a fair few hours of online research and trial and error, I am still no further progressed. I would, therefore, like to seek help unique to this problem and learn in the process.
You can build the layout with CSS flexbox.
For clarity and conciseness, I removed several non-essential decorative styles from the original code. I also used compiled CSS for the benefit of those who don't use preprocessors.
layout 1: [left] [center] [right]
#header-wrap {
display: flex; /* 1 */
align-items: flex-start; /* 2 */
justify-content: space-between; /* 3 */
text-align: center;
padding: 1rem 0;
}
#header-blue { margin-bottom: 50px; background-color: #3498DB; color: #fff; }
.header-left { border: 1px solid red; width: 100px; }
.header-right { border: 1px solid red; width: 100px; }
.header-center { border: 1px solid red; width: 100px; }
<section id="header-blue">
<div id="header-wrap">
<div class="header-left">
<p>1</p>
</div>
<div class="header-center">
<p>2</p>
<p>2</p>
<p>2</p>
<p>2</p>
</div>
<div class="header-right">
<p>3</p>
<p>3</p>
</div>
</div>
</section>
Notes:
Establish flex container.
Prevent flex items from expanding full height (a default setting). The flex-start value will align each item at the start of the cross axis of the container. In this case, that's the top of the vertical (Y) axis. If you want the items vertically centered, use the center value instead. The default value is stretch.
Align flex items horizontally in the container. You can also try justify-content: space-around. Note that this method will only center the middle item in the container if the left and right elements (the back/forward links) are equal width. If the links vary in length, you'll need to use another method (see boxes #71-78 here).
layout 2: [left] [center]
#header-wrap::after { /* 4 */
content: "";
width: 100px;
}
#header-wrap {
display: flex; /* 1 */
align-items: flex-start; /* 2 */
justify-content: space-between; /* 3 */
text-align: center;
padding: 1rem 0;
}
#header-blue { margin-bottom: 50px; background-color: #3498DB; color: #fff; }
.header-left { border: 1px solid red; width: 100px; }
.header-right { border: 1px solid red; width: 100px; }
.header-center { border: 1px solid red; width: 100px; }
<section id="header-blue">
<div id="header-wrap">
<div class="header-left">
<p>1</p>
</div>
<div class="header-center">
<p>2</p>
<p>2</p>
<p>2</p>
<p>2</p>
</div>
</div>
</section>
Notes:
Use an invisible pseudo-element to create equal balance on the opposite end of the container. This is essentially a replacement for the DOM element that was removed from the first example. It keeps the middle item centered.
jsFiddle
Browser Support
Flexbox is supported by all major browsers, except IE 8 & 9.
Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes.
For a quick way to add all the prefixes you need, use Autoprefixer.
More details in this answer.
From your structure you could use flex(IE11) and justify-content, then hide .clearfix and remove it when on fourth position:
with 3 (4 including clearfix)
#header-wrap {
display: flex;
justify-content: space-between;
}
#header-wrap > div {
border: solid;
width: 100px;
margin:0 0 auto;/* remove if you want each boxes same height */
}
.clearfix:nth-child(4) {
display: none;
}
.clearfix {
opacity: 0;
}
<section id="header-blue">
<div id="header-wrap">
<div class="header-left"><p>1</p></div>
<div class="header-center"><p>2</p><p>2</p><p>2</p><p>2</p></div>
<div class="header-right"><p>3</p><p>3</p></div>
<div class="clearfix"></div>
</div>
</section>
when only 2 (3) same CSS involved
#header-wrap {
display: flex;
justify-content: space-between;
}
#header-wrap > div {
border: solid;
width: 100px;
margin:0 0 auto;/* remove if you want each boxes same height */
}
.clearfix:nth-child(4) {
display: none;
}
.clearfix {
opacity: 0;
}
<section id="header-blue">
<div id="header-wrap">
<div class="header-left"><p>1</p></div>
<div class="header-center"><p>2</p><p>2</p><p>2</p><p>2</p></div>
<div class="clearfix"></div>
</div>
</section>
for older browsers.
with your structure you could use text-align, :after and the selector +:
with 3 (4)
#header-wrap {
text-align: justify;
}
#header-wrap:after {
content: '';
display: inline-block;
width: 99%;
}
#header-wrap > div {
display: inline-block;
vertical-align: top;
border: solid;
width: 100px;
}
#header-wrap > div + div + div +.clearfix {
display: none;
}
.clearfix {
opacity: 0;
}
<section id="header-blue">
<div id="header-wrap">
<div class="header-left"><p>1</p></div>
<div class="header-center"><p>2</p><p>2</p><p>2</p><p>2</p></div>
<div class="header-right"><p>3</p><p>3</p></div>
<div class="clearfix"></div>
</div>
</section>
and 2(3) same CSS involved:
#header-wrap {
text-align: justify;
}
#header-wrap:after {
content: '';
display: inline-block;
width: 99%;
}
#header-wrap > div {
display: inline-block;
vertical-align: top;
border: solid;
width: 100px;
}
#header-wrap > div + div + div +.clearfix {
display: none;
}
.clearfix {
opacity: 0;
}
<section id="header-blue">
<div id="header-wrap">
<div class="header-left"><p>1</p></div>
<div class="header-center"><p>2</p><p>2</p><p>2</p><p>2</p></div>
<div class="clearfix"></div>
</div>
</section>
Consider positioning the left and right elements differently.
https://jsfiddle.net/5gxLvp8a/4/
#header-wrap {
text-align: center;
border: 1px solid green;
margin: 0 auto;
padding: 1rem 2.5rem;
position: relative;
div {
display: inline-block;
vertical-align: middle;
}
}
.header-left {
float: left;
border: 1px solid red;
width: 100px;
position: absolute;
left: 25px;
}
.header-right {
float: right;
border: 1px solid red;
width: 100px;
position: absolute;
right: 25px;
}
See code snippet below:
html, html a {
font-size: 10px; }
#header-blue {
width: 100%;
margin-bottom: 50px;
height: auto;
background-color: #3498DB;
color: #fff; }
#header-blue #header-wrap {
text-align: center;
border: 1px solid green;
margin: 0 auto;
padding: 1rem 2.5rem;
position: relative; }
#header-blue #header-wrap div {
display: inline-block;
vertical-align: middle; }
#header-blue .header-left {
float: left;
border: 1px solid red;
width: 100px;
position: absolute;
left: 25px; }
#header-blue .header-right {
float: right;
border: 1px solid red;
width: 100px;
position: absolute;
right: 25px; }
#header-blue .header-center {
border: 1px solid red;
margin: 0 auto !important;
display: inline-block;
width: 100px; }
.clearfix:after {
content: " ";
visibility: hidden;
display: block;
height: 0;
clear: both; }
<section id="header-blue">
<div id="header-wrap">
<div class="header-left"><p>1</p></div>
<div class="header-center"><p>2</p><p>2</p><p>2</p><p>2</p></div>
<div class="header-right"><p>3</p><p>3</p></div>
<div class="clearfix"></div>
</div>
</section>
<section id="header-blue">
<div id="header-wrap">
<div class="header-left"><p>1</p></div>
<div class="header-center"><p>2</p><p>2</p><p>2</p><p>2</p></div>
<div class="clearfix"></div>
</div>
</section>
Widely supported - my immediate answer is to use display: table;
Let me 'fiddle' around with this for a moment and get back to you - I was just working on something similar yesterday.
EDIT 1:
At first glance, I would advise utilizing classes versus ID's. This deals with a much broader topic (CSS Specificity) but is extremely useful to think about early in your career. That being said, I am working on a solution for you, as I THINK I know what you want.
As the commenter mentioned - it would help ALOT to see what you want to see as an end result. From my interpretation of your screenshots (poor quality & non-descriptive FYI), I feel like you want this header to maintain the left/back button and the logo on mobile devices. However, on a desktop/laptop viewport size, you want a forward button to show itself.
If this is incorrect, please verify!
EDIT 2:
Going off the above poster's JSFiddle, I've come up with a "better" solution that stacks the elements within the header as opposed to going outside of the 'container' that it exists in: https://jsfiddle.net/f815aa6y/1/
Still working on the right solution to get this to vertically align in the middle :)