I am rendering a simple view. It consists of an image on the right and some text on the left. This is how it looks like:
return (
<View style={styles.companyContainerStyle}>
<View>
<Text>{this.props.companyNameAr}</Text>
<Text>{this.props.descriptionAr}</Text>
</View>
<View style={styles.imageContainerStyle}>
<Image
style={styles.imageStyle}
source={{ uri: this.props.logo }}
resizeMode='contain'
resizeMethod='auto'
/>
</View>
</View>
);
The following is the styles I applied to make the text and image aligned next to each other:
const styles = {
companyContainerStyle: {
flex: 1,
flexDirection: 'row',
padding: 10
},
imageContainerStyle: {
borderRadius: 5,
borderWidth: 2,
borderColor: '#2279b4',
padding: 1,
},
imageStyle: {
flex: 1,
height: 100,
width: 100,
}
}
The very weird part is that it looks like this on the emulator:
I think the length of the text is pushing the image to the very right out of the screen. I thought that the number of lines would adjust accordingly to fit everything in the screen. However its not the case. How do I make everything look neat given that the length of the text is unknown (it is being rendered from a database)??
#container {
display: flex;
justify-content: space-around;
width: 70%;
height: 400px;;
border: 2px solid grey;
padding: 5px;
}
#top_content {
display: flex;
justify-content: space-around;
align-items: flex-start;
}
#para {
width: 60%;
text-align: justify;
margin: 0px;
}
img {
height: 20%;
width: 20%;
}
<div id="container">
<div id="top_content">
<p id="para">adfasdfadf sadfdaafafdasdfadfadfadfdfad dasadfadfadfadfadgvfa sasadasdaf asdfdfdadfadf</p>
<img src="http://lorempixel.com/400/200" alt="myimg">
</div>
</div>
Something like this can make sure that your text will not push your img outside
Add flex: 1 to imageContainerStyle and also add flex: 1 to View that is container of the two Text components.
Reason for this is that if the Text component does not have container with flex: 1 on it the text will try to take all possible space. The container will restrict that
Related
I am basically trying to create something like this:
Two boxes, the red one is vertical text and the blue one is horizontal text. The height of the red box should be the same as the blue box
I know that I can make text sideways like that by doing:
transform: [{ rotate: '-90deg'}]
on it, but I am having issues getting the rest to work correctly and having the boxes be aligned and sized properly. Any help would be greatly appreciated!
You should really try playing with the layout of React Native and post what you have tried but here's a sample code
<View style={{ height: 100, flexDirection: 'row'}}>
<View style={{ flex: 1, backgroundColor: 'red', alignItems: 'center', justifyContent: 'center' }}><Text style={{transform: [{ rotate: '-90deg'}]}}>Value</Text></View>
<View style={{ flex: 8, backgroundColor: 'blue', alignItems: 'center', justifyContent: 'center'}}><Text>Short Text</Text></View>
</View>
Result:
So little style pointers:
flexDirection is by default column, so if you don't say its a row,
your views will stack vertically
flex fills your screen in the flexDirection. I have 2 elements in my row with flex, so view1 will take up 1/9th of the space and view2 will take up 8/9th
Alignitems will align your items in the direction of your flex, so horizontally if it's a row, vertically if it's a column.
justifyContent aligns item in the crossaxis, so if your flex is a row, it will align items vertically
Ohey its the same as css
This fiddle should get you close: https://jsfiddle.net/1f8png0r/4/
I would stay away from styling using JS at all costs - (mainly $.css() and $.transform(), etc) It is much slower than CSS and CSS is much easier to maintain down the road -- especially if you can learn to style your selectors nicely!
To break it down a little - you want to create a .row a .left column and a .right column. Inside the .left column you want some text. You want to transform that text and rotate it -- rotate(90deg). I have never used the flex vs. inline-flex for this before now, but after needing to do horizontal text a handful of times I think it is the most robust IMHO.
The main focus is to create the grid as you need it, and to transform the content in the left column of the grid relative to the column (rather than relative to the row).
Hopefully this helps get you closer, cheers!
HTML
<div class="row">
<div class="left">
<span class="h-text">LEFT</span>
</div>
<div class="right">RIGHT</div>
</div>
CSS
.row {
width: 756px;
height: 100px;
border: 2px solid green;
display: flex;
justify-content: center;
align-items: center;
color: white;
}
.right {
width: 80%;
height: 100%;
background: red;
display: inline-flex;
justify-content: center;
align-items: center;
}
.left {
width: 20%;
height: 100%;
background: blue;
position: relative;
display: inline-flex;
justify-content: center;
align-items: center;
}
.left .h-text {
position: absolute;
transform: rotate(-90deg);
}
you could do this.
https://codepen.io/anon/pen/yGepmm
This is an aproach using flexbox. I use sass for clear syntax (no ; )
.sass
div:first-child
display: flex
justify-content: center
align-items: center
transform: rotate(270deg)
width: 100px
background: blue
color: white
text-align: center
vertical-align: middle
div:nth-child(2)
display: flex
padding-left: 2rem
background: lightgreen
justify-content: start-end
align-items: center
color: grey
height: 91px
width: 100%
.html
<section>
<div>
Value
</div>
<div>
Lorem Ipsum
</div>
</section>
It's a very less code implementation, you will have to calculate for now, manually the:
height of div:first-child (which it's the width because the
rotation).
And the height div:nth-child(2).
Hope this helps
I implemented this way giving fixed height and some tweak with flex:
<View style={{flex: 1, paddingTop: 40}}>
<View style={{ flexDirection: 'row', height: 100 }}>
<View style={{ backgroundColor: 'red', justifyContent: 'center' }}>
<Text
style={{
textAlign: 'center',
transform: [{ rotate: '-90deg' }],
}}>
Value
</Text>
</View>
<View
style={{
flex: 1,
backgroundColor: 'aqua',
alignItems: 'center',
justifyContent: 'center',
}}>
<Text>Some text here....</Text>
</View>
</View>
</View>
Here is the link to snack if you want to play around. Might have extra unnecessary styles. You can play with it in the snack.
I hope, you got the idea?
https://snack.expo.io/#roshangm1/humiliated-cookies
I have to build a CSS grid system. Here is some of my initial code:
#carousel-data{
display: grid;
grid-template-columns: 3% 40% 54% 3%;
grid-template-rows: 10% 10% 60% 20%;
align-content: center;
height: 72vh;
margin-top: 8.5vh;
}
.carousel-text-title{
grid-column-start:3;
grid-row:2/3;
justify-self:start;
font-size:2.5em;
margin-left:30px;
font-weight:bold;
color:white;
}
.carousel-text-content{
grid-column-start: 3;
grid-row: 3/4;
justify-self: start;
margin-top:50px;
margin-left:30px;
font-size:2rem;
color: white;
}
The first part is the container and the other two are some element that are placed in the said container.
This works just fine. But then I found out I had to make the container responsive, that is to modify it's height based on the content displayed. So i went ahead and changed the height property to min-height thinking this would do the trick. But when I ran the code, everything was messed up. Some rows were missing and elements that had their size specified with % or had set only a max height/width weren't showing.
I can't figure out what am I doing wrong. Can you help me out please? Thanks in advance!
Edit:
Here is the HTML fragment(can't put it up on codepen because it's a React App,it would be irrelevant, I can link the github repository if that would be helpful) :
<div className="carrousel">
<div className="grid-container">
<PageIndicator size={this.props.data.length} activeIndice={this.state.currentIndice}
style={{gridColumnStart:'second',justifySelf:'center',marginTop:'30px'}}
/>
</div>
<div id="carousel-data" style={this.state.slideBackgroundStyle} className={this.state.style}>
<Arrow style={{ gridColumnStart: '1', gridRow: '3', justifySelf: 'center', alignSelf: 'center' }}
orientation='left' onClick={this.changeSlide} />
<div className="carousel-image" style={{gridColumnStart:'2/3',gridRow:'2/4' ,justifySelf:'center'}}>
<img src={this.props.data[this.state.currentIndice].picture}
style={this.props.data[this.state.currentIndice].style ?
{ ...this.props.data[this.state.currentIndice].style, display: "inline-block", maxWidth: '95%', maxHeight: '100%' } : { display: "inline-block", maxWidth: '95%', maxHeight: '100%' }} />
</div>
<div className="carousel-text-title">
{this.props.data[this.state.currentIndice].title}
</div>
<div className="carousel-text-content" >
{this.props.data[this.state.currentIndice].text}
</div>
<Arrow style={{ gridColumnStart: '4', gridRow: '3', justifySelf: 'center', alignSelf: 'center' }}
orientation='right' onClick={this.changeSlide} />
</div>
</div>
I'm trying to create this layout in Flexbox (and React Native) but I can't get it to work. Specifically, the Left and Right buttons refuse to expand to 50% of the width of the container no matter what I do. They are always the size of their content.
I'm using nested containers. The buttons are in a columnar Flex container which is nested in a row Flex container that also contains the image.
Here is my JSX:
<View style={{
display: 'flex',
flex: 1,
flexDirection: 'column'}}>
<Image
style={{flex: 1, zIndex: 1, width: '100%', height: '100%'}}
resizeMode='cover'
resizeMethod='resize'
source={require('./thumbs/barry.jpg')}
/>
<View style={{
display: 'flex',
flexDirection: 'row',
flex: 0,
width: '100%',
height: 100}} >
<Button style='flex: 1' title="LEFT" onPress={() => {}} />
<Button style='flex: 1' title="RIGHT" onPress={() => {}} />
</View>
</View>
All replies are much appreciated...
Maybe this will help you:
.container{
display: flex;
flex-wrap: wrap;
width: 500px;
}
.image{
height: 500px;
flex-basis: 100%;
background-color: green;
}
.button{
box-sizing: border-box;
flex-basis: 50%;
height: 100px;
background-color: red;
border: solid 1px black;
}
<div class="container">
<div class="image"></div>
<div class="button"></div>
<div class="button"></div>
</div>
If you ever have issues with using flexbox, use this resource, it's really helpful for solving flexbox issues. Hopefully you can solve your problem now.
You dont want to use height properties, but using it is a good way to achieve what you want. Here is an example:
You set the image to 90% of the screen height and the buttons container to 10%.
Each button has 50% width
HTML
<div class="container">
<div class="image"></div>
<div class="buttons-container">
<button>Action 1</button><button>Action 2</button>
</div>
</div>
CSS
* {
box-sizing: border-box;
}
body, html {
height: 100%;
margin: 0;
}
.container {
position: relative;
width: 100%;
height: 100%;
}
.container .image {
width: 100%;
height: 90%;
background-image: url('path/to/image');
position: relative;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.container .buttons-container {
display: flex;
height: 10%;
}
.container .buttons-container button {
width: 50%;
}
Check the example working - https://codepen.io/kaiten/pen/YaYqZO
In consideration of the fact that your code is required in react-native and not react, try this piece of code
<View style={flex:1}>
<Image source={require(path)} style={flex:1}>
<View style={flex:1}>
<View style={flex:1}>
<Button style={flex:1,height:100} title='Left'/>
</View>
<View style={flex:1}>
<Button style={flex:1,height:100} title='Right'/>
</View>
</View>
</View>
Explanation : In react-native you do not need to mention display:flex in your styles since react-native always uses flexBox. When you do flex:1 your container always takes the 100% of the width and the height of it's parents hence doing flex:1,height:'100%',width:'100%' is invalid.
In your
<View style={{
display: 'flex',
flexDirection: 'row',
flex: 0,
width: '100%',
height: 100}} >
you've done flex:0 so this is the equivalent of width:'0%',height:'0%'
Hope this gives you some clarity on the code required.
PS: There might be a possibility that the code i wrote might not work properly due to the <Image> width and height. For eg : If the height of the image decreases and you've given fixed height to your buttons then there might be some white space below your buttons since the height of the <Image> plus the height of the <Button> will not add up to the height of the screen visible.
It seems like Button component do not take style as prop if we look at the codebase of React Native. So the problem is button is not accepting style. So I wrapped button with a view.
Here is sample of working code:
<View style={{
flex: 1,
}}>
<Image
style={{ flex:1, zIndex: 1, width: '100%', height: '100%'}}
resizeMode='cover'
resizeMethod='resize'
source={require('./thumbs/barry.jpg')}
/>
<View style={{
flexDirection: 'row',
height: 100}} >
<View style={{flex:1}}>
<Button title="LEFT" onPress={() => {}} />
</View>
<View style={{flex:1}}>
<Button title="RIGHT" onPress={() => {}} />
</View>
</View>
</View>
I'd like to have an element overlapping onto an image in react native. I'm new in react native but could do this in CSS in 3 lines of code:
container in position relative.
element in position absolute + bottom: 20px.
Here is my react native code and a screenshot of what it looks like.
<ScrollView style={styles.container}>
<Image
style={styles.profileImage}
source={{uri: blabla}}
/>
<View style={styles.iconContainer}>
<ActionIcon
name={'mode-edit'}
color={colorBrand}
onPress={() => console.log('test')}
/>
</View>
<List containerStyle={styles.list}>
<ListItem
title={'Account Settings'}
/>
<ListItem
title={'Notifications'}
/>
<ListItem
title={'Terms & Conditions'}
/>
<ListItem
title={'Privacy Policy'}
/>
<ListItem
title={'Log Out'}
/>
</ScrollView>
and StyleSheet:
const styles = StyleSheet.create({
container: {
flex: 1
},
profileImage: {
height: 250
},
list: {
borderTopWidth: 0,
flex: 1,
marginTop: 0
},
iconContainer: {
alignSelf: 'flex-end',
right: 10,
bottom: 40,
marginBottom: -60,
zIndex: 1
}
})
So it looks like:
So it looks like exactly like I want it. But I am not liking that zIndex, nor that negative bottomMargin.
I first tried with a container of the iconContainer in position relative, then the iconContainer in position absolute. But to have it displayed you had to set a height. Then you have a white space full width and of the set height with the icon at the right. Which pushes the list down and adds a big white space.
Is there any other options?
Cheers
Add the css property, position: 'absolute' to the element you want to overlap.
I will suggest you to wrap your image and icon in a div and then play with position css
Stack Snippet
.wrapper {
margin-bottom: 40px;
position: relative;
display: inline-block;
}
.wrapper i {
position: absolute;
right: 20px;
bottom: -25px;
width: 50px;
height: 50px;
background: #5ab985;
font-size: 30px;
color: #fff;
text-align: center;
line-height: 50px;
border-radius: 50%;
}
.wrapper img {
display: block;
}
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div class="wrapper">
<img src="http://lorempixel.com/200/200/sports">
<i class="material-icons">mode_edit</i>
</div>
I have two pieces of text. I need the first piece to be centered horizontally and vertically, and the second to just be right next to it. Currently the code looks like this:
<View style={styles.runningTimeWrapper}>
<Text style={styles.loggedTime}>00:00</Text>
<Text style={[styles.loggedTime, styles.loggedSeconds]}>00</Text>
</View>
How can I style it so the 00:00 is centered? Using fixed widths is not an option as I need this to work on any screen size.
Here is how it looks currently:
Styles:
loggedTime: {
color: Variables.PURPLE,
fontSize: 44,
alignSelf: 'center',
},
loggedSeconds: {
fontSize: 22,
alignSelf: 'flex-end',
paddingBottom: 8
},
runningTimeWrapper: {
flexDirection: 'row',
justifyContent: 'center',
flex: 1,
},
The desired effect is to have the column of hh:mm aligned with the center of the screen, and the seconds directly next to the minutes.
On all 'center' references, I am talking about horizontal center (x-axis), not vertical(y-axis) (which is set using alignItems /self)
You can set the second span to position:absolute, so it will be out of the normal content flow, and ensure the hour/minute to be centered in the container.
.wrapper {
display: flex;
justify-content: center;
position: relative;
font-family: sans-serif;
}
.hm {
font-size: 44px;
}
.s {
font-size: 22px;
position: absolute;
bottom: 5px;
}
<div class="wrapper">
<span class="hm">12:34</span>
<span class="s">56</span>
</div>
In fact, you don't really need flexbox, the text-align:center is probably enough to do it.
.wrapper {
text-align: center;
position: relative;
font-family: sans-serif;
}
.hm {
font-size: 44px;
}
.s {
font-size: 22px;
position: absolute;
bottom: 5px;
}
<div class="wrapper">
<span class="hm">12:34</span>
<span class="s">56</span>
</div>
You'll need 3 inner wrapper views: an empty one on the left and then wrap the small and big numbers in their own wrapper each. Then give the left and right wrappers flex: 1 to make them the same width.
https://rnplay.org/apps/hLBFng
I'm not 100% certain I understand what you're going for. Are you trying to get the loggedTime to be perfectly centered and the loggedSeconds to be offset to the right of that? Or are you simply trying to get both to be center/center?
I think I was able to get something going here by setting flexDirection: 'row' and adding some paddingTop to the seconds.
Here's a demo on rnplay.org
var styles = StyleSheet.create({
loggedTime: {
color: '#FF5500',
fontSize: 44,
alignSelf: 'center',
},
loggedSeconds: {
fontSize: 22,
paddingTop: 20,
paddingBottom: 8
},
runningTimeWrapper: {
flexDirection: 'row',
justifyContent: 'center',
flex: 1,
},
});