I am trying to understand flex box:
I want to make the “first” block stretched to match the full width of the browser, and the ”second” block of fixed size and aligned to left.
So I used align-items: flex-end in the parent(<html>) and tried to stretch the first block using align-self: stretch in the ”first” block.
This is not working. Both of them are aligned to the left.
<html>
<head>
<style>
html {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-end;
}
#first {
align-self:stretch;
background-color: red;
border: 3px solid black;
}
#second {
background-color:green;
width: 300px;
height: 400px;
border: 3px solid yellow;
}
</style>
</head>
<body>
<div id="first">This is first</div>
<div id="second">This is second</div>
</body>
</html>
So the problem is that you've got the <html> node as a flex container, and the <body> node (its child) is the one and only flex item.
Currently, align-self:stretch on #first is ignored, because that property only applies to flex items, and #first is not a flex item (the way you have things set up right now).
To get what you want, you need to make the <body> node a flex container, not the <html> node. So, just change your first style rule to apply to body{ instead of html{
(Also, if you want #second to be aligned to the left, you need flex-start, not flex-end. The left edge is the flex-start horizontal edge, generally.)
Add flex:1 to #first
Remove justify-content: flex-start; and align-items: flex-end; from html
See example: http://codepen.io/anon/pen/vifIr
Related
HTML
<div id="flexbox-container">
<h1 id="test1">test1</h1><h1 id="test2">test2</h1><h1 id="test3">test3</h1>
</div>
CSS
#flexbox-container {
display:inline-flex;
}
#test1 {
float:left;
}
#test2 {
justify-content:center;
align-items:center;
text-align:center;
align-self:center;
align-content:center;
}
#test3 {
position:relative;
left:1000px;
}
Why does test2 not center itself in the flex? I would prefer not to have to set px or margin to get it to centre. I tried all sorts of aligning stuff on it yet it still sticks to the left. I need the three items to be inline, so setting it to flex wouldn't work (though it does center align if I make it flex), PLEASE HELP IVE BEEN TRYING FOR DAYS
https://codepen.io/throwaway123/pen/mdpJJKY
Only this much code is enough. No need for all those styles for separate h1 tags. You have to give the aligning styles to the parent div.
#flexbox-container {
width: 100%;
display:inline-flex;
justify-content: space-between;
}
<div id="flexbox-container">
<h1 id="test1">test1</h1>
<h1 id="test2">test2</h1>
<h1 id="test3">test3</h1>
</div>
Basically that isn't how flex works.
You don't want the contents of the second item to be justified within itself, you want the container to have that element centered.
If you scrap all the positioning of the three items you can get flex to do the work for you. There are several ways of telling it how you want the items set out in the line. For example justify-content: space-between.
From MDN:
The items are evenly distributed within the alignment container along the main axis. The spacing between each pair of adjacent items is the same. The first item is flush with the main-start edge, and the last item is flush with the main-end edge.
#flexbox-container {
display: inline-flex;
justify-content: space-between;
width: 100vw;
}
<div id="flexbox-container">
<h1 id="test1">test1</h1>
<h1 id="test2">test2</h1>
<h1 id="test3">test3</h1>
</div>
Using IDs for css is bad practice. I'd suggest you to start using class selectors
Anyway, here is solution to your problem :
<style>
#flexbox-container {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
If you want the h1 tags centered too you can wrap the h1 tag by a div. Then you can assign the div text-align: center CSS Property.
#flexbox-container {
background: green;
display:flex;
justify-content: space-between;
text-align: center;
}
#flexbox-container div {
width: 100%;
}
<div id="flexbox-container">
<div>
<h1 id="test1">test1</h1>
</div>
<div>
<h1 id="test2">test2</h1>
</div>
<div>
<h1 id="test3">test3</h1>
</div>
</div>
I have below markup for testing flexbox:
<html>
<head>
<style>
.parent{
display: flex;
flex-direction: column;
}
.parent>div>button{
display: flex;
}
.parent>div:nth-child(2){
display: flex;
}
</style>
</head>
<body>
<div class="parent">
<div class="div1"><button>butt1</button><button>butt7</button></div>
<div class="div2"><button>butt2</button><button>butt3</button><button>butt4</button>
<button>butt5</button><button>butt6</button></div>
</div>
</body>
</html>
Its output is given below:
What I don't understand is that even if we haven't given any flex-direction: column to the div1 i.e., we haven't written:
.parent>div>button{
display: flex;
flex-direction: column;
}
even then butt1 and butt7 are aligned in column. Why they are not aligned in row?? Is it the case that child div inherits the value of flex-direction of parent? I have read that default value of flex-direction is row. So, with that logic as well, they should have been aligned row-wise, not column-wise.
Please help me to find the reason of above behaviour.
Thank You.
The problem is in this:
.parent>div>button{
display: flex;
}
You overwritten default style of button, which is display: inline-block. display: flex works for children not for element itself, so your buttons behave like normal div (display: block). If you want to use flex in your way even if it's inappropriate change it to display: inline-flex.
More precise information directly from specification:
flex -
This value causes an element to generate a flex container box that is block-level when placed in flow layout.
inline-flex - This value causes an element to generate a flex container box that is inline-level when placed in flow layout.
#IMPROVEMENT
You have a lot of code that is not needed.
You can achieve same result by:
.parent > div {
display: flex;
}
<div class="parent">
<div>
<button>butt1</button>
<button>butt7</button>
</div>
<div>
<button>butt2</button>
<button>butt3</button>
<button>butt4</button>
<button>butt5</button>
<button>butt6</button>
</div>
</div>
If you want to apply a flex to the div1 do it like this:
.parent>.div1{
display: flex;
}
See here, I've added a background color for you to see what's going on:
.parent {
background: red;
display: flex;
flex-direction: column;
}
.parent>.div1 {
background: blue;
margin: 10px;
display: flex;
}
.parent>div:nth-child(2) {
background: green;
margin: 10px;
display: flex;
}
<div class="parent">
<div class="div1">
<button>butt1</button><button>butt7</button>
</div>
<div class="div2">
<button>butt2</button><button>butt3</button><button>butt4</button>
<button>butt5</button><button>butt6</button>
</div>
</div>
this line of CSS is the issue:
.parent>div>button{
display: flex;
}
You are telling css CSS using > that rules will be applied to elements which are direct children of the .parent -> div -> button element.
.parent {
display: flex;
flex-direction: column;
}
.parent>div:nth-child(2) {
display: flex;
}
<div class="parent">
<div class="div1"><button>butt1</button><button>butt7</button></div>
<div class="div2"><button>butt2</button><button>butt3</button><button>butt4</button>
<button>butt5</button><button>butt6</button></div>
</div>
I have a flexbox container (div) with two divs inside: one contains text, another one contains canvas.
When I reduce width of a flexbox first div shrinks but second div doesn't.
.flex-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: grey;
}
.textdiv {
background-color: #f1f1f1;
margin: 10px;
line-height: 75px;
font-size: 30px;
}
.canvasDiv {
background-color: DodgerBlue;
}
<html>
<head></head>
<body>
<div class="flex-container">
<div class="textdiv">1111111111 123123123121</div>
<div class="canvasDiv">
<canvas id="canvas"></canvas>
</div>
</div>
</body>
</html>
JSFiddle
UPDATE: I want to have a Chart (Chart.js) inside my canvas (which shrinks when I reduce width of a flexbox) - it should look something like:
Howto solve this problem?
Thank you.
that's because the canvas has Width:auto as Default value, The browser calculates the width of the canvas, to solve this you need to set max width or width 100% of their parent.
I have a parent with overflow-y and a fixed height. I wish to center align its child. The content of the child can vary in size, and sometimes it overflows the parent and triggers a scrollbar. In those cases, the top and bottom content of the child is cut out.
I wish the child to be center aligned, but only if it's smaller than the parent. Or it could always be center aligned, but then the content shouldn't be cut out.
Check out the problem here: https://jsfiddle.net/gumy023z/
.parent {
background-color: red;
height: 40px;
overflow-y: scroll;
/* Comment out the flex, and all the content will be available */
display: flex;
justify-content: center;
align-items: center;
}
<div class="parent">
<div class="child">
This is a test <br> This is a test <br> This is a test
</div>
</div>
The alignment will work in the flex axis of a flexbox. So you can switch to a column flexbox and give min-height: 0 (which overrides the default min-width: auto setting for a flex item) for the child element - see demo below:
.parent {
background-color: red;
height: 40px;
overflow-y: auto;
display: flex;
flex-direction: column; /* ADDED */
justify-content: center;
align-items: center;
}
.child {
min-height: 0; /* ADDED */
}
<div class="parent">
<div class="child">
1. This is a test <br> 2. This is a test <br> 3. This is a test
</div>
</div>
I am using CSS FlexBox to design my website. (See example below)
In FlexBox, "Flex:1" attribute will make sure all the items in the container are re-sized according to the widest item.
However, in Internet Explorer 10/11 this does not work unless you specify the width of the item. (Using flex-basis). The problem is that once you specify a flex-basis value, it becomes static and no longer shrinks or grows according to the content.
Is there some solution in IE without making the width static?
Thanks!
Example (IE - Bug, Chrome - Correct Behaviour): https://codepen.io/dsomekh/pen/BRoreL
<html>
<style>
.parent{
display: flex;
justify-content:center;
}
.table{
display:flex;
flex-direction:row;
}
.element{
flex:1;
border: 5px solid skyblue;
display:flex;
}
</style>
<div class="parent">
<div class="table">
<div class="element">First element - small.</div>
<div class="element">Second element - contains more text and first element will resize accordingly. How do we acheive this in IE?</div>
</div>
</div>
</div>
</html>
Updated
In this case IE need a width set, combined with flex: 1 1 0
.parent {
display: flex;
justify-content: center;
}
.table {
display: flex;
/* flex-direction: row; row is default so this is not needed */
}
.element {
flex: 1 1 0; /* changed */
width: 100%; /* added */
border: 5px solid skyblue;
display: flex;
}
<div class="parent">
<div class="table">
<div class="element">First element - small.</div>
<div class="element">Second element - contains more text and first element will resize accordingly. How do we acheive this in IE?</div>
</div>
</div>