why is flex-basis size not being applied? - html

I have an input element which I want to grow and shrink using flex shrink but its flex-basis size is not being applied.
Here is my html:
<input type="text"/>
and my css:
input{
background-color: black;
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
flex: 0 1 450px;
}
why is the basis size not being applied? it is getting set to a much smaller width than 450px.
Here is a fiddle with the example.

You have applied display: flex to the <input> element instead of a div.
The ideal way is to use a container/wrapper and then make the container display: flex & then control the input using flex-basis - Here is your Fiddle updated
HTML
<div class="container">
<input type="text"/>
</div>
CSS
.container{
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
}
.container input { flex: 0 1 450px; }

You need to establish a flex formatting context.
This is the same as establishing a block formatting context, except
that flex layout is used instead of block layout.
For properties like flex-basis, flex-grow, flex-shrink to work, an element must participate in the flex formatting context.
A flex item establishes a new formatting context for its contents. The
type of this formatting context is determined by its display value, as
usual. However, flex items themselves are flex-level boxes, not
block-level boxes: they participate in their container’s flex
formatting context, not in a block formatting context.
var el = document.querySelector("input");
console.log("input width: " + el.offsetWidth + "px");
.flex-container { /* Flex formatting context, this makes the element a flex container */
display: flex;
}
input { /* Direct children of flex containers are now flex items */
background-color: black;
flex: 0 1 450px;
box-sizing: border-box;
}
<section class="flex-container">
<input type="text" />
</section>
Revised jsFiddle
Source: W3C CSS Flexible Box Layout Module Level 1

/* Latest compiled and minified CSS included as External Resource*/
/* Optional theme */
#import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
body {
margin: 10px;
display:flex;
}
input{
background-color: black;
align-items: center;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
flex: 0 1 450px;
}
<input type="text"/>
check this

Apply flex properties to a input container rather than to the input.
Have a look at the snippet below:
.input-holder {
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
}
.input-holder input {
flex: 0 1 450px;
background: #000;
}
<div class="input-holder">
<input type="text"/>
</div>
Hope this helps!

Related

Flex wrap column: fill the available width with columns

I have items of different sizes in the flex container which I want to display in several columns of different widths, depending on the content. flex-flow: column wrap works good for me with fixed container height but I have fixed width for container and want the height depending on the content. I.e. I want as many columns as fit in width.
Example, how it must look:
.container {
height: 80px;
display: flex;
align-items: flex-start;
justify-content: flex-start;
flex-flow: column wrap;
align-content: left;
}
.container > span {
margin: 3px 12px;
background: #ebd2b5
}
<div class="container">
<span>Apple</span>
<span>Apricot</span>
<span>Avocado</span>
<span>Banana</span>
<span>Bilberry</span>
<span>Blackberry</span>
<span>Blackcurrant</span>
<span>Blueberry</span>
<span>Boysenberry</span>
<span>Currant</span>
<span>Cherry</span>
<span>Cherimoya</span>
<span>Cloudberry</span>
<span>Coconut</span>
</div>
Any solutions with CSS?
No. With pure css you can't.
However if you use align-content: stretch; You can distribute the current columns to the entire container width.
.container {
height: 80px;
display: flex;
align-items: flex-start;
justify-content: flex-start;
flex-flow: column wrap;
align-content: stretch;
}
.container > span {
margin: 3px 12px;
background: #ebd2b5
}
<div class="container">
<span>Apple</span>
<span>Apricot</span>
<span>Avocado</span>
<span>Banana</span>
<span>Bilberry</span>
<span>Blackberry</span>
<span>Blackcurrant</span>
<span>Blueberry</span>
<span>Boysenberry</span>
<span>Currant</span>
<span>Cherry</span>
<span>Cherimoya</span>
<span>Cloudberry</span>
<span>Coconut</span>
</div>

Weird wrapping of text and anchor element in flex container

I have a simple block of text sharing a display: flex container with an <a> tag.
Unfortunately, the wrapping is a bit weird, almost as if the <a> tag's "true" width isn't being treated as such, or like it has a width of 0 (judging by how it is positioned).
Is there some styling I can apply to <a> tags to make it act more "text-like"?
JSFiddle
body {
font-size: 32px;
}
body > .container {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: center;
}
body > .container > .foot {
flex: 1 0 100%;
background-color: grey;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
}
body > .container > .foot > .content {
flex: 1 0 70%;
width: 50%;
height: 350px;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: center;
align-content: center;
text-align: center;
}
<div class='container'>
<div class='foot'>
<div class='content'>
We'll be back up shortly. We are undergoing a scheduled maintenance. Apologies for the inconvenience. Check <a href='http://status.mywebsite.com'>http://status.mywebsite.com </a> for updates.
</div>
</div>
</div>
Answer
You have text-align: center which is applying to the text, but not the anchor element.
You have justify-content: flex-start which is applying to the anchor element, but not the text.
All you need is a switch to justify-content: center.
revised fiddle
body {
font-size: 32px;
}
body > .container {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: center;
}
body > .container > .foot {
flex: 1 0 100%;
background-color: grey;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
}
body > .container > .foot > .content {
flex: 1 0 70%;
width: 50%;
height: 350px;
display: flex;
flex-flow: row wrap;
justify-content: center; /* ADJUSTED */
align-items: center;
align-content: center;
text-align: center;
}
<div class='container'>
<div class='foot'>
<div class='content'>
We'll be back up shortly. We are undergoing a scheduled maintenance. Apologies for the inconvenience. Check <a href='http://status.mywebsite.com'>http://status.mywebsite.com </a> for updates.
</div>
</div>
</div>
Explanation
You wrote:
I have a simple block of text sharing a display: flex container with an <a> tag.
Well, your block of text isn't as simple as you might think.
You're not dealing with a single string.
What you actually have is a flex container with three flex items:
An anonymous flex item wrapping the text before the anchor element
The anchor element
An anonymous flex item wrapping the text after the anchor element
From the spec:
4. Flex Items
Each in-flow child of a flex container becomes a flex item, and each
contiguous run of text that is directly contained inside a flex
container is wrapped in an anonymous flex item.
The behavior you're seeing is three flex items wrapping.
The anchor text itself will not wrap because it is equivalent to a single word. But if you add spaces and text in the anchor it will wrap like everything else.
Also see this post:
Why do I need "text-align: center" when the container has "justify-content: center"?

flex basis not applied when two divs containing the element

I have an input element which I want to grow and shrink using flex shrink but its flex-basis size is not being applied.
Here is my html:
<div class="flex-container">
<div class="flex-row">
<input type="text" name="query" class="searchbar" />
</div>
<div>
and my css:
.flex-container{
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
flex-wrap: wrap;
}
.flex-row input { flex: 0 1 450px; }
why is the basis size not being applied? it is getting set to a much smaller width than 450px.
Here is a fiddle with the example.
Actually what is happening here is that your input's immediate parent .flex-row is a simple div with no css properties and also not set to be a flex container hence it's width is auto and wrapping around the input and not applying the flex properties. To apply flex properties to the input use the following css to make the input's parent display be flex.
.flex-container{
display: flex;
}
.flex-row {
display: flex;
flex:1;
align-items: center;
justify-content: center;
}
.flex-container input { flex: 0 1 450px; }
Hope this helps.

Make ancestor flexbox divs only take up the width of its child with a set width

I have an input element using flex display and I set its flex-basis width like so:
.flex-row input { flex: 0 1 450px; }
and a flex-row div is contained inside of a flex-container div.
I want the flex-row to only take up the width that the input takes.
When I give flex-container display: flex it takes up 100% width.
When I give it display: inline-flex it compresses the input making it much smaller than 450px.
I don't really care about the width of flex-container, although it would be nice for it to take up the width of its child as well, but how do I make flex-row have the same width as the input (namely, when there is enough room for it, 450px)?
.flex-container {
display: flex;
}
.flex-row {
display: flex;
flex: 1;
align-items: center;
justify-content: center;
}
.flex-row input {
flex: 0 1 450px;
}
<div class="flex-container">
<div class="flex-row">
<input type="text" name="query" class="searchbar" />
</div>
</div>
and here is a fiddle example.
Add the same flex property to the flex-row as you have on the flex-row input.
.flex-row{
display: flex;
flex: 0 1 450px;
align-items: center;
justify-content: center;
}
If you want the row to be centered as well then add the align and justify properties to the flex-container as follows.
.flex-container{
display: flex;
align-items: center;
justify-content: center;
}

using a flex item as a flex container

I wanted to use flexbox with a column layout, but I wanted the top n - 1 flex items to be pinned to the top and the nth flex item to be pinned to the bottom of the main flex container area.
I solved this by using the nth flex item to also be a new flexbox/flex container using justify-content: flex-end, but I couldn't find any examples that were doing this - so is this a correct/acceptable solution according to the standard and, if not, how would I otherwise go about this with flexbox?
Here's a quick example:
.flex-container {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
width: 300px;
height: 240px;
background-color: Silver;
}
.flex-container-bottom {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
width: 300px;
height: 240px;
background-color: orange;
-webkit-justify-content: flex-end;
-ms-flex-pack: end;
justify-content: flex-end;
}
.flex-item {
background-color: DeepSkyBlue;
width: 100px;
height: 100px;
margin: 5px;
}
.flex-item-bottom {
background-color: red;
width: 100%;
height: 50px;
}
<div class="flex-container">
<div class="flex-item">flex item 1</div>
<div class="flex-item flex-container-bottom">
<div class="flex-item-bottom">flex item 2</div>
</div>
</div>
The spec isn't very clear on this, but it states that "Each in-flow child of a flex container becomes a flex item, and each contiguous run of text that is directly contained inside a flex container is wrapped in an anonymous flex item." This seems to imply that if I put a flex container inside another flex container that the inner flex container would also implicitly become a flex item for its containing flex container even if this is not explicitly defined. Example 1 of the specification shows a flex container within a flex container and assuming it is legal syntax it follows that my use case may also be legal, but the section with example 1 is marked as non-normative... (╯°□°)╯︵ ┻━┻... At this point I'm just going to assume this is correct.
It's hard to say that your use of flex-end is wrong because you're getting the desired effect, but there's an easier way to do it.
Try using:
.flex-container{
display: flex;
justify-content: space-between;
flex-direction: column;
}
justify-content: space-between; forces your flex items to spread out as much as possible in the flex container.
This is the reference guide I use whenever doing anything with flexboxes:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
You can also try this this will make your last item to stick to bottom of your parent container
.flex-container{
position:relative;
}
.flex-item-bottom{
position:absolute;
bottom:0;
}