I'm getting different behavior between Safari and Chrome/FF/Edge using flex-grow. I'm trying to get a vertical center, but safari is giving more of a fixed to bottom effect.
I'm using flex-grow with a decimal, but Safari seems to interpret it as a whole value.
HTML
<div class="fc">
<div>Align Top</div>
<div>Align Center</div>
<div>Align Bottom</div>
<div class="spacer">Bottom Spacer</div>
</div>
CSS
.fc {
height: 100%;
width: 100%;
background-color: darkBlue;
color: gold;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
.fc div {
outline: 2px dashed gold;
padding: 15px;
width: 200px;
text-align: center;
}
.fc div:first-child {
outline: 1px dashed salmon;
padding: 15px;
flex-grow: .5;
opacity: .5;
}
Here's the pen: https://codepen.io/dmgig/pen/NvMKJW
Problem behavior on Safari 10 (10.12)
Desired behavior on other browsers
If you make the body a flex container, set the fc to flex-grow: 1 (and remove height: 100%) it will render as you want
Updated codepen
Stack snippet
html, body {
width: 100%;
height: 100%;
font-family: sans-serif;
font-size: 20px;
}
body {
display: flex;
flex-direction: column;
}
.fc {
flex-grow: 1;
width: 100%;
background-color: darkBlue;
color: gold;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
.fc div {
outline: 2px dashed gold;
padding: 15px;
width: 200px;
text-align: center;
}
.fc div:first-child {
outline: 1px dashed salmon;
padding: 15px;
flex-grow: .5;
opacity: .5;
}
.fc div.spacer {
outline: 1px dashed salmon;
padding: 0;
height: 60px;
width: 200px;
text-align: center;
opacity: .5;
padding: 15px;
}
.footer {
position: fixed;
bottom: 0;
height: 75px;
width: 100%;
background-color: salmon;
color: darkBlue;
opacity: .5;
font-weight: bold;
}
<div class="fc">
<div>Align Top</div>
<div>Align Center</div>
<div>Align Bottom</div>
<div class="spacer">Bottom Spacer</div>
</div>
<div class="footer">
footer
</div>
You can also remove the position: fixed on the footer and make it all more responsive
Updated codepen 2
I found a bug report here: https://github.com/philipwalton/flexbugs/issues/182
It suggests just using a percentage height on the element and removing flex-grow altogether, which does indeed work well for the purpose.
.fc div:first-child {
outline: 1px dashed salmon;
padding: 15px;
height: 25%;
opacity: .5;
}
Related
I am getting white space between my parent div and child div when adding a border to the parent div. I have tried everything (overflow, (min) height/width, increasing border width) but nothing works. I have the same problem with images when.
Does someone know how I can fix this and why this is happening?
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body,
html {
margin: 0;
padding: 0;
}
.container {
margin: auto;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
height: 100vh;
width: 100vw;
}
.big-box {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
background: white;
border: 5px solid darkgreen;
overflow: hidden;
height: 100px;
width: 100px;
}
.box {
flex: 1 1 33%;
min-height: 100%;
min-width: 100%;
background: black;
color: white;
border: none;
overflow: hidden;
}
<div class="container">
<div class="big-box">
<div class="box">
<h2>hello</h2>
</div>
</div>
</div>
Yes, I have come across this and I think it is related to fractions of a CSS pixel being interpreted in different ways when the system is mapping them to actual screen pixels, there being more than one screen pixel to a CSS pixel on many modern screens. The calculations of course vary on different zoom settings and so sometimes you can see the extra white and sometimes not depending on zoom level.
A practical, if hacky, way of getting round this is to give the parent the same background color as the child if that doesn't mess up other stuff in your styling.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body,
html {
margin: 0;
padding: 0;
}
.container {
margin: auto;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
height: 100vh;
width: 100vw;
}
.big-box {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
background: white;
border: 5px solid darkgreen;
overflow: hidden;
height: 100px;
width: 100px;
background-color: black;
}
.box {
flex: 1 1 33%;
min-height: 100%;
min-width: 100%;
background: black;
color: white;
border: none;
overflow: hidden;
}
<div class="container">
<div class="big-box">
<div class="box">
<h2>hello</h2>
</div>
</div>
</div>
If that messes up your styling I suppose you could go one (hackier) step further and use linear-gradient backgrounds on the parent to give it a sort of black inner border of a (CSS) px or two and leave the rest as white.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body,
html {
margin: 0;
padding: 0;
}
.container {
margin: auto;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
height: 100vh;
width: 100vw;
}
.big-box {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
background: white;
border: 5px solid darkgreen;
overflow: hidden;
height: 100px;
width: 100px;
background-image: linear-gradient(black 0 2px, transparent 2px calc(100% - 2px), black calc(100% - 2px) 100%), linear-gradient(to right, black 0 2px, white 2px calc(100% - 2px), black calc(100% - 2px) 100%);
}
.box {
flex: 1 1 33%;
min-height: 100%;
min-width: 100%;
background: black;
color: white;
border: none;
overflow: hidden;
}
<div class="container">
<div class="big-box">
<div class="box">
<h2>hello</h2>
</div>
</div>
</div>
I have a page wrapped in a container that has a 100vh height. I need this in order to be able to vertically center the content of the other pages later.
However, on the homepage, I can't add a header with a 100vh background image anymore because of this.
I could do hacky stuff with javascript such as "if you are on homepage, height is 100% else it's 100vh" but it's quite ugly and I'd prefer to handle it with pure css.
How to do it?
Here is the code:
html:
export default function App() {
return (
<div className="App">
<header/>
<div className="content-wrapper">
<div className="content">
<h3>content</h3>
</div>
<footer>footer</footer>
</div>
</div>
);
}
css:
body {
margin: 0;
background: black;
}
.App {
font-family: sans-serif;
text-align: center;
display: flex;
flex-direction: column;
height: 100vh;
}
header {
padding: 24px;
color: white;
border: 1px solid white;
height: 100vh;
background-image: url("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSVHPI0EekAVTf_xKei3cwTsvvi3PChxaXeIA&usqp=CAU");
background-size: cover;
background-repeat: no-repeat;
}
.content-wrapper {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
color: white;
height: 100%;
flex: 1;
}
.content {
border: 1px solid orange;
padding: 24px;
width: 100%;
margin-bottom: 24px;
}
footer {
border: 1px solid yellow;
padding: 24px;
height: 100px;
width: 100%;
}
Here is also a sandbox: https://codesandbox.io/s/happy-wright-c85gi?file=/src/App.js:24-287
body {
margin: 0;
background: black;
height:100vh;
}
This question already has answers here:
Fill the remaining height or width in a flex container
(2 answers)
Closed 2 years ago.
I'd like to display some "dots" in between a label and a price, like this:
from..........£2,000.49
total........£20,000.00
However, the dots must "adapt/reduce/increase", if the length of the price increases. (Like in the example above), as the prices are dynamic and not static/hardcoded.
I thought I would try this with flex. I have a working example below, where I have two columns, in two rows.
There is no width on the .price-big class, so the width of these divs increases/decreases, with the length of the numbers.
I am then adding the dots to the label class. However, this then pushes my divs onto separate lines/stacked, like in the example below.
.label {
content: ".............................................";
}
Any ideas on how to achieve this, would be helpful as I'm kinda getting stuck on this one.
Thank you,
Reema
.main {
display: flex;
flex-wrap: wrap;
align-items: baseline;
border: 1px solid green;
width: 200px;
}
.label {
font-size: 14px;
/* flex: 0 50%; */
flex-basis: 50%;
flex-shrink: 1;
flex-grow: 1;
border: 1px red solid;
/* width: 100%; */
text-align: left;
font-size: 14px;
}
.label:after {
content: ".............................................";
}
.price-big {
flex-basis: 0;
flex-shrink: 1;
flex-grow: 1;
border: 1px red solid;
text-align: right;
font-size: 20px;
}
<div class="main">
<div class="label">price</div>
<div class="price-big total">£2,000.49</div>
<div class="label">total</div>
<div class="price-big">£20,000.00</div>
</div>
You may combine float and flex to modify the formating context layout of the non floatting element and use a pseudo to fill that empty space inside it:
your CSS code modified :
.main {
/*display: flex;
flex-wrap: wrap;
align-items: baseline;*/
border: 1px solid green;
width: 200px;
overflow:hidden; /* because of the float label */
}
.label {
font-size: 14px;
/* flex: 0 50%;
flex-basis: 50%;
flex-shrink: 1;
flex-grow: 1; */
border: 1px red solid;
/* width: 100%;
text-align: left;*/
font-size: 14px;
margin-top:0.4em;
float:left;
clear:left;
}
.price-big {
border: 1px red solid;
font-size: 20px;
display:flex;
}
.price-big:before {
content:'';
border-bottom:dotted;
margin-bottom:0.2em;
flex-grow:1;
}
<div class="main">
<div class="label">price</div>
<div class="price-big total">£2,000.49</div>
<div class="label">total</div>
<div class="price-big">£20,000.00</div>
</div>
Omg, I literally figured out the answer one minute after posting this. I added overflow: overlay; to the label class:
.label {
font-size: 14px;
flex-basis: 50%;
flex-shrink: 1;
flex-grow: 1;
border: 1px red solid;
text-align: left;
font-size: 14px;
overflow: overlay; <--- added this
}
.main {
display: flex;
flex-wrap: wrap;
align-items: baseline;
border: 1px solid green;
width: 200px;
}
.label {
font-size: 14px;
/* flex: 0 50%; */
flex-basis: 50%;
flex-shrink: 1;
flex-grow: 1;
border: 1px red solid;
/* width: 100%; */
text-align: left;
font-size: 14px;
overflow: overlay;
}
.label:after {
content: ".............................................";
}
.price-big {
flex-basis: 0;
flex-shrink: 1;
flex-grow: 1;
border: 1px red solid;
text-align: right;
font-size: 20px;
}
<div class="main">
<div class="label">price</div>
<div class="price-big total">£2,000.49</div>
<div class="label">total</div>
<div class="price-big">£20,000.00</div>
</div>
I am creating a card that will have an image, a title, and a button taking someone to the URL of the program. Since the title will be dynamically generated by the content, I will have no way of knowing how long the title will actually be. I want my card, specifically the card bottom, to grow to show all the text. What is the best way of achieving this??
.program{
height: 250px;
width: 200px;
background-color: red;
/* display: flex;
felx-direction: column; */
}
.program_top{
width: 100%;
height: 50%;
background-color: purple;
background-image: url('https://images.unsplash.com/photo-1581309638082-877cb8132535?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60');
background-repeat: no-repeat;
background-size: cover;
}
.program_bottom{
width: 100%;
height: 50%;
background-color: rgb(32, 32, 32);
display: flex;
flex-direction: column;
justify-content: space-around;
}
.program_title{
padding: 10px;
color: white;
}
.program_button{
text-align:center;
margin-bottom: 20px;
}
.program_button a {
color: orange;
text-decoration: none;
border: 2px solid orange;
padding: 0 30px;
border-radius: 15px
}
<div class="program">
<div class="program_top">
</div>
<div class="program_bottom">
<div class="program_title">
Security For Small Business asfdasdfasdfasdfasdfasdfasdfasdfsdfasdfasdfasdfasdfasdf
</div>
<div class="program_button">
View Program
</div>
</div>
</div>
Here is a codepen for it:
codepen
I changed your CSS to accomplish your needs. Please let me know if you need any additional help.
CSS
.program{
height: auto;
width: 200px;
background-color: red;
display: flex;
flex-direction: column;
}
.program_top{
width: 100%;
height: 125px;
background-color: purple;
background-image: url('https://images.unsplash.com/photo-1581309638082-877cb8132535?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60');
background-repeat: no-repeat;
background-size: cover;
}
.program_bottom{
width: 100%;
height: 50%;
background-color: rgb(32, 32, 32);
display: flex;
flex-direction: column;
justify-content: space-around;
}
.program_title{
padding: 10px;
color: white;
}
.program_button{
text-align: center;
margin-bottom: 20px;
}
.program_button a {
color: orange;
text-decoration: none;
border: 2px solid orange;
padding: 0 30px;
border-radius: 15px
}
On option is to fix the height and basically hide any extra content using
.program_title {
padding: 10px;
color: white;
overflow: hidden;
text-overflow: ellipsis;
}
This helps you to avoid any unexpected layout growth when the info on this container is too big.
The problem is when you need to show all this information, in this case you can provide another way to display the full text (a popup with details, mouseover hint)
.program{
height: 250px;
width: 200px;
background-color: red;
/* display: flex;
felx-direction: column; */
}
.program_top{
width: 100%;
height: 50%;
background-color: purple;
background-image: url('https://images.unsplash.com/photo-1581309638082-877cb8132535?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=60');
background-repeat: no-repeat;
background-size: cover;
}
.program_bottom{
width: 100%;
height: 50%;
background-color: rgb(32, 32, 32);
display: flex;
flex-direction: column;
justify-content: space-around;
}
.program_title {
padding: 10px;
color: white;
overflow: hidden;
text-overflow: ellipsis;
}
.program_button{
text-align:center;
margin-bottom: 20px;
}
.program_button a {
color: orange;
text-decoration: none;
border: 2px solid orange;
padding: 0 30px;
border-radius: 15px
}
<div class="program">
<div class="program_top">
</div>
<div class="program_bottom">
<div class="program_title">
Security For Small Business asfdasdfasdfasdfasdfasdfasdfasdfsdfasdfasdfasdfasdfasdf
</div>
<div class="program_button">
View Program
</div>
</div>
</div>
im a bit lost:
im trying to make the space between 3 divs (horizontally) 40px, but it doesnt seem to work when i do it:
https://github.com/itsolidude/Tea_Cozy
i want the yellow marked parts to be 40px:
html {
font-family: Helvetica;
font-size: 22px;
color: seashell;
background-color: black;
opacity: 0.9;
text-align: center;
}
header {
display: flex;
align-items: center;
justify-content: space-between;
height: 69px;
border-bottom: 1px solid seashell;
position: fixed;
width: 100%;
z-index: 2;
background-color: black;
top: 0;
}
#locations h2 {
flex: 1 0 100%; /* shorthand for: flex-grow:1;
flex-shrink: 0;
flex-basis: 100%; */
text-align: center;
position: absolute; /* found this to be a simpler solution, and i sticked with it even tho i dont have exact 10px :p */
top: 1510px;
z-index: 3;
}
img {
height: 50px;
padding-left: 10px;
}
nav span {
color: seashell;
padding-right: 30px;
}
.mission-banner {
background-color: black;
}
.mission-banner h4 {
padding-bottom: 10px;
}
a {
cursor: pointer;
text-decoration-color: seashell;
}
#mission {
background-image: url(../images/img-mission-background.jpg);
position: relative;
margin: 70px auto 0;
width: 1200px;
height: 700px;
display: flex;
flex-direction: column;
justify-content: center;
}
#tea-of-month {
display: flex;
flex-wrap: wrap;
justify-content: center;
width: 1000px;
margin: 0 auto 70px;
}
#tea-of-month img {
height: 200px;
width: 300px;
margin-bottom: 10px;
}
.item {
display: flex;
flex-direction: column;
padding: 10px;
}
.contact {
height: 200px;
}
#locations {
height: 500px;
width: 1200px;
margin: 0 auto;
background-image: url(../images/img-locations-background.jpg);
display: flex;
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
}
.address {
background-color: black;
width: 300px;
height: 300px;
display: flex;
flex-direction: column;
justify-content: center;
opacity: 1;
}
#copyright {
text-align: left;
margin-left: 20px;
}
<div id="locations">
<h2>Locations</h2>
<div class="address">
<h3>Downtown</h3>
<p>384 West 4th St</p>
<p>Suite 108</p>
<p>Portland, Maine</p>
</div>
<div class="address">
<h3>East Bayside</h3>
<p>3433 Phisherman's Avenue</p>
<p>(Northwest Corner)</p>
<p>Portland, Maine</p>
</div>
<div class="address">
<h3>Oakdale</h3>
<p>515 Crescent Avenue</p>
<p>Second Floor</p>
<p>Portland, Maine</p>
</div>
</div>
i put in the whole css. just in case something is affecting it. Pls explain what and why you did it :p
Don't use justify-content: space-between; as this will allot space depending on the available space.
Instead, center the flex-children and give them side margin of 20px (2 * 20px = 40px).
.wrap {
display: flex;
justify-content: center;
width: 90%;
margin: auto;
border: 1px solid grey;
}
.box {
background: #000;
width: 150px;
height: 150px;
margin: 20px;
}
<div class="wrap">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
Alternatively, you could set a max-width of the parent container, thus making less available space for the children to spread out with the space-between style.