React Native Stylesheet: what does {flex:1} do? - flexbox

React Native uses flexbox for layout. In all of the examples I've seen, they do something like this:
var styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row'
}
});
I'm curious about the flex: 1 part. Based on Chris Coyier's definition here https://css-tricks.com/snippets/css/a-guide-to-flexbox/, flex: 1 should be the same as flex-grow: 1, but to me it looks like flex: 1 in React Native is equivalent to display: flex in CSS.
Here's a CodePen that demonstrates that flex: 1 the way React Native examples use it doesn't do anything in CSS:
http://codepen.io/johnnyo/pen/BoKbpb
It's not until we use display: flex in CSS until flexbox starts to work:
http://codepen.io/johnnyo/pen/epZXgz
So does this mean that flex: 1 in React Native is equivalent to display: flex in CSS?

There is quite a difference between css flexbox and the one implemented by Facebook. Lots of things in common but defaults are very different. Specifically:
Everything is display: flex by default. All the behaviors of block and inline-block can be expressed in term of flex but not the opposite.
flex: attribute is only used when at the same level there are few components with different flex values (flex: 1, flex: 3) means that the second element should be 3 times bigger than the first one. flex attribute is the only one supported (no grow/shrink support).
More info: https://github.com/facebook/css-layout

A remark to Jarek Potiuk's answer: 'flex: 1' does do something in react-native similar to flex-grow behavior. Even if it is the only one with flex: defined.
Styles such as flexDirection, alignItems, justifyContent all define styling of children of the element. Similar to CSS Display: flex, which also defines children.
In contrast, flex: x defines the element itself.
E.g. if a container component has flexDirection: 'row', alignItems: 'center'
And there are 3 children:
child 1 has width 50
child 2 has flex 1 (or any other number, but 1 is common practice)
child 3 has width 50
Then the middle component will 'stretch' so that the 3 children together fill the entire width of the parent component.

A lot of tutorials use flex: 1, much like as you did in your example. The main reason is because sometimes (depending on the element, such as ListStyle by default, if my memory serves) the component will not take up the entire screen/area if you do not define the dimensions, such as the height (eg. height: '400px'). Flex: is awesome because it keeps things responsive for various sizes.
But I should note that for any component with no siblings, the value for flex is totally arbitrary. Ex. for your top-level component, you could say flex: 43254315 and it does the same thing as flex: 1. It just means "take up the entire space" (whatever "entire" that may be).
On the other hand, if you have some sibling components, then the flex value matters a lot. For example, if one component is flex: 2 and another is flex: 3, then the first takes up 2/5 of the screen and the second takes up 3/5 of the screen.
In short: Depending on your styles, it might look like flex: 1 is the same as display: flex, but that's only because of the way you are using it in your example. You'll see it act very differently if you just give it some siblings.

Like you I struggled to understand this tag that isn't documented properly on Facebook Code, but I eventually discovered that it does two things:
Containers consider any children with a flex attribute to have a height of 0 for the purpose of determining how much space they take up.
Components with flex: X expand to take up any room remaining in their container after other components have been laid out. They share this extra space in proportion with their X values.
The first item is why flex: 1 can appear to have the same effect as display: flex. Consider the following JSX code:
<ExampleAppContainer>
<Text>
I get printed.
</Text>
<Text style={{flex: 1}}>
But I don't :(
</Text>
</ExampleAppContainer>
Only the first text component gets printed, because the second one is considered to have a height of 0. ExampleAppContainer allocates enough space for the first text component, and there isn't any room for the second one to expand.
Now consider this code:
<ExampleAppContainer style={{flex:1}}>
<Text>
I get printed.
</Text>
<Text style={{flex: 1}}>
And so do I!
</Text>
</ExampleAppContainer>
Since ExampleAppContainer has flex: 1, it expands to take up as much room as it can. Assuming that it is the root component for the React part of your app, this is usually going to be the entire phone screen. Next it allocates sufficient space for the first text component, and allows the second text component to expand, taking up the rest of the screen.
In this fashion you will often need to apply flex: 1 all the way down you component hierarchy in order to allow your innermost components with flex: N room to expand properly.

flex: 1
Tells a component to fill all available space (shared amongst other components with the same parent).
If there are sibling components with flex values, their parent needs to have flex: 1 (or higher). If a parent does not have either a fixed width and height or flex, the parent will have dimensions of 0 and the flex children will not be visible.

this is very simple just think that when you say flex: 1 to any elements that element get all height of parent element if this element have flex: 1 and dont have parent element get all height of screen size.
for example you want have one container element that get all height of screen and this element have three child element that each element have 1/3 height of screen
for this example just get the parent element flex: 1 and three child element flex: 1/3
see code bellow
<View style={{flex: 1,backgroundColor: 'red'}}>
<View style={{flex: 1/3, backgroundColor: 'green'}}></View>
<View style={{flex: 1/3, backgroundColor: 'yellow'}}></View>
<View style={{flex: 1/3, backgroundColor: 'pink'}}></View>
</View>

Related

Use react-virtualized Window Scroller with frozen header and footer

I am using react-virtualized WindowScroller with CellMeasurer to scroll through a 100 sample records and by itself, it works great.
Now, when I place this component in a content pane with a frozen header and footer (using flex) above and below it, react-virtualized does not bring in additional data beyond the first page.
The structure of my container page is the same as the create-react-app template:
<div className="App">
<div className="App-header" />
<div className="App-intro" />
<div className="App-footer" />
</div>
and here is the CSS I use to freeze the header and footer:
html, body, #root {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.App {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.App-header, .App-footer {
flex-shrink: 0;
}
.App-intro {
flex-grow: 1;
overflow-y: auto;
}
FWIW, the official WindowScroller example accomplishes a frozen header using flex, but try as I might, I am not able to replicate it on my end.
I am at my wit's end after spending a whole entire day on this. I would really really appreciate any pointers to get this flex layout going with a functional window-scroller.
In the CodeSandbox you linked to (codesandbox.io/s/52j0vv936p)- window "scroll" events aren't reaching WindowScroller. That's because the window isn't actually what's scrollable, rather it's the middle "body" part. If that's what you want, you don't need to use WindowScroller at all and should remove it.
The only thing left that's broken is that your AutoSizer isn't getting a valid height because one of its parent <div>s doesn't have a correct height. For Stack Overflow convenience, here's the relevant bit:
Why is my AutoSizer setting a height of 0?
AutoSizer expands to fill its parent but it will not stretch the parent. This is done to prevent problems with flexbox layouts. If AutoSizer is reporting a height (or width) of 0- then it's likely that the parent element (or one of its parents) has a height of 0. One easy way to test this is to add a style property (eg background-color: red;) to the parent to ensure that it is the correct size. (eg You may need to add height: 100% or flex: 1 to the parent.)
Here is a diff to your sandbox that shows what I'm talking about and here is a fixed Code Sandbox demo.

React virtualized - Padding bottom on List

I was wondering if there is any way to add a padding bottom at the end of the list.
I need this because I have a material floating button over the list, at the bottom. So if the user goes to the end of the list, that padding will save the last item to be covered from the button.
thankyou
Its not a padding, but you could put a margin botton to the div that contains all the items
Something like that:
.ReactVirtualized__Grid__innerScrollContainer {
margin-bottom: 100px;
}
.ReactVirtualized__Grid__innerScrollContainer[style] {overflow:visible !important;}
Version 9 of react-select uses inline styles to set overflow. I used this so the tooltip was seen below the end of the grid (when the grid doesn't take the whole screen). See react select library code snippet:
<div
className="ReactVirtualized__Grid__innerScrollContainer"
role={containerRole}
style={{
width: autoContainerWidth ? 'auto' : totalColumnsWidth,
height: totalRowsHeight,
maxWidth: totalColumnsWidth,
maxHeight: totalRowsHeight,
overflow: 'hidden',
pointerEvents: isScrolling ? 'none' : '',
position: 'relative',
...containerStyle,
}}>
And that is in https://github.com/bvaughn/react-virtualized/blob/438b5672e5364cffa91f21656ee2f04003794ca1/source/Grid/Grid.js#L1058
You could set the height of the last item in your list to include your padding, as rowHeight can be passed a function.
Then all you need to do is style your list items such that the extra height on the last item is empty space, margin bottom or a fixed height on the inner contents would work.
https://github.com/bvaughn/react-virtualized/blob/master/docs/List.md#prop-types.

How to set the width of suggest boxes in RedQueryBuilder

After you have chosen a field name, then you start typing in the value textbox, the dropdown defaults to a width of 150px which causes lots of things to be cut off. A scrollbar shows up so you can scroll left and right, but I would like to figure out how to set the minimum width of this element.
The css path to the element defining this is:
body > div.gwt-SuggestBoxPopup > div > table > tbody > tr.suggestPopupMiddle > td.suggestPopupMiddleCenter > div > div
It seems to be an inline style in the element
<div class="" style="overflow: auto; position: relative; zoom: 1; height: 322px; width: 150px;">
The field dropdown seems to re-size dynamically, so it does not get scroll bars, the suggest box starts at 150px and resizes sometimes, but it doesn't seem to have any rhyme or reason.
I added the following to my stylesheet:
.suggestPopupMiddleCenter > div > div
{
min-width: 300px; !important
}
But that also affects the field dropdown, which appears to be working properly.
Is this a bug, or is there a configuration that I can use that will allow the value suggestion box dropdown to dynamically resize based on the widest element?
It is hard wired in the tardis branch https://github.com/salk31/RedQueryBuilder/blob/tardis/redquerybuilder-core/src/main/java/com/redspr/redquerybuilder/core/client/expression/SuggestEditorWidget.java#L107
It probably could use some rule to choose the width. Best if you raise a bug and make a suggestion?

Calculate value with CSS3

Is there any way to achieve this in CSS3?:
height: 100% -110px;
My context:
You can't calulate it with pure CSS. (it will not work in all browsers, as mentioned by Litek ) But there is a organizational way to handle this, but you will need to wrap you element in a other one:
body {
height; 100%;
padding: 0 0 20px;
}
div#wrap {
background: #fff;
height: 100%;
padding: 0 0 20px;
margin: 0 0 -20px;
}
div#wrap div { //this would be your actual element
height: 100%;
background: pink;
}
What you want to use is calc() that is comming to FF and propably webkit, but don't count on it being widely supported anytime soon.
As for your example, maybe sticky footer will be some inspiration for you.
Edit
Nowadays it's well supported by major browsers:
http://caniuse.com/calc
Directly like that i'm not aware of any feature widely adopted to do that.
But there is a easy method to achieve the effect.
Put all element inside a container <div> with 'height: 100%', this container should have position relative so you can position the other elements inside it relative to its position. place the header on top and the footer at bottom with absolute positioning and calculate with javascript the height that the content div must have.
You can also subscribe the 'window.onResize' event to recalculate when the window is resized.
I know this is not a clean and prety solution, but is the one the you can make work well in almost any browser.
In the context it was given the 2nd div height value doesn't really matter. Actually it's only important where that div starts and where it ends.
In other words height = vertical end - vertical start:
#div2 {
position:absolute;
top:90px;/*20+50+20*/
bottom:20px;
}
http://jsfiddle.net/cGwrw/3/

Resizable page with min-width and position absolute?

I'm working on a resizable page with a sidemenu to the right, and it almost works as supposed on this simple example:
http://pastehtml.com/view/1do8cy9.html
The problem though is that position auto and min-width dont react as expected. If you drag the browserwindow smaller than 500px (as the min-width is set to), the red sidemenu continues over the green content..
How do I make the sidebar stop when it reaches the min-width, fx 500px?
The absolute positioned div should be inside the min width div which should have position relative
Edit, better explanation:
For the sidebar: add top: 0 to the red sidebar and place it inside the min-width container.
For the container: replace the margin-right property with padding-right and add position:relative
I have a fix !
It's weird though:
body{
position:absolute;
top:0;
left:0;
bottom:0;
min-width:1300px;
width:100%;
overflow:auto;
padding:0;
margin:0;
}

Resources