How to make flexbox 'justify-content: space-between' have effect? - html

I want to create following layout, where a header (green) spans the full width of the screen and is made up of two elements:
a picture (pink), that is top-left aligned, and has the height of the next element
a text block (red), that is top-right aligned. It made of two stacked elements: a text div (yellow) and a button. The width button equals the text width.
The expected output is this:
My code is the following:
.header{
background-color: green;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.flex-element{
display: inline-block;
}
.picture_container{
background-color: pink
}
.picture{
height: 100%;
}
.text_container{
background-color: red
}
.text{
background-color: yellow;
}
<div class="header">
<div class="flex-element picture_container">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/55/Tux_Enhanced.svg/154px-Tux_Enhanced.svg.png" alt="" class="picture">
</div>
<div class="flex-element text_container">
<div class="text">
AAAAAAAAAA <br>
BBB
</div>
<button type="button" name="button" style="width: 100%">foo</button>
</div>
</div>
and gives following output:
The problem is that there is no "space-between" the pink and the red block, and they are not top aligned. I know I could work around it using css grid, yet I'd like to know why it isn't working.
Question: How to make justify-content: space-between have any effect?

This might be a browser issue. Indeed, I am using Firefox Developer Edition 63.0b14 as a browser.
A hack was then to add display: -moz-box; in the .header css definition. It is strange, though, as "Prefixed property values (such as -moz-box) are no longer needed for flexbox to work in major browsers." (see Michael_B's comment). A less hacky solution would hence be still appreciated.
Full code:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>test</title>
<style media="screen">
.header{
background-color: green; 
display: -moz-box;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.flex-element{
display: inline-block;
}
.picture_container{
background-color: pink
}
.picture{
height: 100%;
}
.text_container{
background-color: red
}
.text{
background-color: yellow;
}
</style>
</head>
<body>
<div class="header">
<div class="flex-element picture_container">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/55/Tux_Enhanced.svg/154px-Tux_Enhanced.svg.png" alt="" class="picture">
</div>
<div class="flex-element text_container">
<div class="text">
AAAAAAAAAA <br>
BBB
</div>
<button type="button" name="button" style="width: 100%">foo</button>
</div>
</div>
</body>
</html>

Please try below code
<style>
.header {
padding: 10px;
}
.picture {
width: auto;
}
.text_container {
margin: auto 0;
}
.picture_container {
display: block;
}
</style>

Related

CSS - Centered image and text below it

I want to display a centered image and, below it, a centered and bordered text that has a width equal to its container. I use:
<!DOCTYPE html>
<html>
<head>
<style>
.d1 {
text-align: center;
}
.d2 {
border: 1px solid red;
display: inline-block;
}
</style>
</head>
<body>
<div class="d1">
<img src="smiley.gif"><br>
<div class="d2">This is some text</div>
</div>
</body>
</html>
This works fine but, as I read, the use of <br> is an indication of poor semantic HTML and should be avoided. Is there a way to do this without the use of <br>?
Thanks
Flexbox to the rescue:
.d1 {
display: flex;
flex-flow: column;
justify-content: center;
}
.d2 {
border: 1px solid red;
}
img, .d2{
margin: 0 auto;
}
<div class="d1">
<img src="https://placekitten.com/200/300">
<div class="d2">This is some text</div>
</div>
The semantically correct element to use is the HTML5 figure element ( documentation here ) - this is a block level element and has the figcaption element and the image element contained within it.
The figcaption can be the first child (ie - before the image) or last child (after the image) and is also a block level element and can be centered with css.
<!DOCTYPE html>
<html>
<head>
<style>
figure {
text-align: center;
}
figcaption {
margin-bottom: 10px;
}
</style>
</head>
<body>
<figure>
<figcaption>This is a fluffy kitten</figcaption>
<img src="https://cdn.unifiedcommerce.com/content/product/small/30106.jpg" alt="fluffy kitten" width="100">
</figure>
</body>
</html>
Try using a div to enclose your image. A div is a block element, meaning, it will occupy 100% of the parent width. In your case, if the img tag is inside div, then all contents outside the div will be in the next line automatically.
img {
max-width: 100px;
}
.d1 {
text-align: center;
}
.d2 {
border: 1px solid red;
display: inline-block;
}
<div class="d1">
<div>
<img src="https://demo-res.cloudinary.com/image/upload/sample.jpg">
</div>
<div class="d2">This is some text</div>
</div>
You can try this.Just use margin for the text section instead of <br> tag. And then for positioning both of the image and text to center, use the following property:
display: flex;
justify-content: center;
align-items: center;
flex-flow: column;
<!DOCTYPE html>
<html>
<head>
<style>
.d1 {
display: flex;
justify-content: center;
align-items: center;
flex-flow: column;
}
.d2 {
border: 1px solid red;
margin-top: 5px;
}
</style>
</head>
<body>
<div class="d1">
<img src="https://www.w3schools.com/howto/img_snow.jpg">
<div class="d2">This is some text</div>
</div>
</body>
</html>

Viewport is changing zoom when Flexbox container is running out of space

My page starts to change zoom and layout gets slightly messed up when I have a hardcoded width on items located in a Flexbox container (make a very narrow Chrome Devtools responsive window). The problem starts when I make my viewing area narrower than the 300px. Unfortunately, you can't see this problem when running this inside an iframe on jsfiddle - it has to be ran "on it's own", my html block needs to be THE top html block.
Here's the jsfiddle for reference still:
https://jsfiddle.net/elijahww/9e1u7ptr/
<html><head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#productShowcaseContainer {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
}
.contentContainer {
display: flex;
flex: 1;
}
#productShowcaseTitle {
height: 100px;
background-color: antiquewhite;
}
#productShowcaseThumbnailContainer {
flex: 1;
background-color: darkseagreen;
}
</style>
</head>
<body style="margin: 0;">
<div id="productShowcaseContainer">
<div id="productShowcaseTitle"></div>
<div class="contentContainer">
<div id="productShowcaseThumbnailContainer" style="padding: 10px;">
<input style="width:300px;">
</div>
</div>
</div>
</body></html>
I don't know how to make this work.
here is a gif:
This might be happening because you have hard-coded width of input field as 300px and trying to zoom screen width beyond this.
If you really want to have responsive layout then you should be using flex-layout properly and set flex-basis, flex-grow and flex-shrink property of each layout element.
These properties are responsible for handling responsive behaviour of flex-elements.
To Read more about flex layout follow this link Flex tutorial
One option is to give some parent container overflow-x: auto
body {
background-color: #3d5d6a;
}
#container {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
}
.main-content-container {
display: flex;
flex: 1;
}
#top-header-container {
padding: 10px;
height: 100px;
background-color: antiquewhite;
/*align-content: stretch;*/
display: flex;
justify-content: stretch;
}
#main-content-inner {
flex: 1;
background-color: darkseagreen;
}
.responsive-table {
overflow-x: auto;
}
<html><head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body style="margin: 0;">
<div id="container">
<div id="top-header-container">
<div class="responsive-table">
<input style="width:400px;" value="hard coded to 400px">
</div>
</div>
<div class="main-content-container">
<div id="main-content-inner" style="padding: 10px;">
test
</div>
</div>
</div>
</body></html>

Undesired margin between flexboxes when viewed on mobile

I've got an issue on my webpage that involves margins popping up next to flexboxes when the site is viewed on mobile. I've distilled the issue down to some pretty simple code.
HTML Code
<html>
<head>
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="container">
<!-- When you remove this period, issue goes away -->
.
<div class="smallboxes">
<div class="smallbox1">
</div>
<div class="smallbox2">
</div>
</div>
<div class="bigbox">
</div>
</div>
</body>
</html>
CSS code
.container {
display: flex;
height: 100px;
}
.bigbox {
flex: 2;
background-color: #6e6e6e;
display: flex;
}
.smallboxes {
flex: 1;
display: flex;
flex-direction: column;
}
.smallbox1 {
flex: 2;
background-color: #6e6e6e;
}
.smallbox2 {
flex: 1;
}
When you run the code in Chrome, right-click, click "Inspect", view as IPad Pro in horizontal mode and change the view to 75% or 125%. You'll see a white line between the two boxes. This is showing up on my Note 5 as well. There should be no line between the two grey boxes.
As I mention in the code, when you remove the period, the issue goes away.
Thanks a ton for the help!
P.S. I'm new to SO and can't seem to figure out how insert the "run codepen on this code" button. I'm including a link to the codepen version of this as well.
http://codepen.io/jasonhoward64/pen/XMpYXJ
edit: new answer based on comments of author
I've been playing with your Codepen and the problem is because of the use of "Flex: 1". Flex creates the needed space inside your "container". if you give ".bigBox" flex:2; and ".smallBoxes" flex:1; it will divide ".container" into 3 parts where bigBox will take up 2. When you add an item inside the container without giving it a flex-value, it will try to calculate the needed space.
Try placing the dot inside a span or div (or other element) and give it a flex-value. This will solve your problem.
.container {
display: flex;
height: 100px;
background: red
}
.bigbox {
flex: 5;
background-color: #6e6e6e;
display: flex;
}
.testBox {
background: yellow;
flex: 1;
}
.smallboxes {
flex: 3;
display: flex;
flex-direction: column;
}
.smallbox1 {
flex: 2;
background-color: #6e6e6e;
}
.smallbox2 {
flex: 1
}
<html>
<head>
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="container">
<!-- When you remove this period, issue goes away --> <span class="testBox">test</span>
<div class="smallboxes">
<div class="smallbox1">
</div>
<div class="smallbox2">
</div>
</div>
<div class="bigbox">
</div>
</div>
</body>
</html>
You're code works, but when you add margin of 0 to the body, it breaks again. Do you know why?
body {
margin: 0;
}
.container {
display: flex;
height: 100px;
background: red
}
.bigbox {
flex: 5;
background-color: #6e6e6e;
display: flex;
}
.testBox {
background: yellow;
flex: 1;
}
.smallboxes {
flex: 3;
display: flex;
flex-direction: column;
}
.smallbox1 {
flex: 2;
background-color: #6e6e6e;
}
.smallbox2 {
flex: 1
}
<html>
<head>
<link href="style.css" rel="stylesheet">
</head>
<body>
<div class="container">
<!-- When you remove this period, issue goes away --> <span class="testBox">test</span>
<div class="smallboxes">
<div class="smallbox1">
</div>
<div class="smallbox2">
</div>
</div>
<div class="bigbox">
</div>
</div>
</body>
</html>

Display:flex stretching percentage width images

I am trying to code a responsive icon-based menu bar. I am using display:flex to do this but the issue I am having is that the images keep wanting to stretch or squish horizontally when the page is scaled up or down. If they would just move relative to each other and scale uniformally that would be the better solution.
What am I doing wrong?
<!DOCTYPE html>
<html>
<head>
<style>
#A {
display: flex;
justify-content: space-around;
}
.B {
width: 15%
}
</style>
</head>
<body>
<div id="A">
<img class="B" src="http://tinyurl.com/h9zm7bp">
<img class="B" src="http://tinyurl.com/h9zm7bp">
<img class="B" src="http://tinyurl.com/h9zm7bp">
<img class="B" src="http://tinyurl.com/h9zm7bp">
<img class="B" src="http://tinyurl.com/h9zm7bp">
</div>
</body>
</html>
To have display: flex distribute the space without squishing images, you can convert the images into, say, <div>s and set the images as backgrounds with background-size: contain.
<!--- ... --->
<style>
#A {
}
.B {
width: 15%;
background-image: url("http://tinyurl.com/h9zm7bp");
background-size: contain;
}
</style>
<!-- ... -->
<div id="A">
<div class="B"></div>
<div class="B"></div>
<div class="B"></div>
</div>
Also, for some reason, setting a %-based height works:
#A {
display: flex;
justify-content: space-around;
}
.B {
width: 15%;
height: 1%; /* literally any % works here for some reason */
}
Here's a CodePen to demonstrate:
http://codepen.io/milaniliev/pen/eZgZJz
I have no explanation for why that works. It seems the actual height % is ignored.
Try this:
#A {
display: flex;
justify-content: space-around;
flex-wrap: wrap;
}
.B {
max-width:100%;
}
You can use px instead of % and use the following code
#A {
overflow: auto;
}
#B {
float: left;
width: (in px);
}

vertically centering two divs within body

This is a simplified version of a more complex problem. Suppose there are two divs within the body, which have to be vertically centered. Because of some other requirements DOM can't change. So only by changing css I need to vertically align them center. I have tried many other stackoverflow posts but so far couldn't make it work.
Here is my code:
<!DOCTYPE html>
<html>
<head>
<style>
body{
}
.div1{
display: block;
background: red;
width: 300px;
}
.div2{
display: block;
background: green;
width: 300px;
}
</style>
</head>
<body>
<div class="div1">
<p>This is div1</p>
</div>
<div class="div2">
<p>This is div2</p>
</div>
</body>
</html>
This is possible using flexbox.
html,
body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
See this CodePen