I am trying to use Flexbox in my React app to create a simple two column webpage that occupies the full width and height.
I can get this to work with HTML and CSS on their own but not within a React app.
So far I have:
:root {
overflow-x: hidden;
height: 100%;
}
body {
min-height: 100%
}
.flexbox {
height: 100%;
display: flex;
}
.left {
flex: 0 0 200px;
height: 100%
}
.right {
flex: 1
}
and:
<div class="flexbox">
<div class="left">
Left
</div>
<div class="right">
Right
</div>
</div>
I realise that I need to account for the additional <div id="root"></div> tag in my index.html so I have also added the following to my css:
#root {
height: 100%;
}
And my render function:
render() {
return (
<div className="flexbox">
<div className="left">Left</div>
<div className="right">Right</div>
</div>
)
}
but this doesn't work. The columns exist but are not full height. Why not?
If you use create-react-app, it adds an element with class=App and an element with id=root to the DOM. They should also get height: 100%
html, body, #root, .App {
height: 100%;
}
Use viewport height units in css:
#root {
min-height: 100vh;
}
You forgot that <html> is also a tag. Moreover, it is parent to all parents! That's why you should give it height of 100% as well.
html, body {
height: 100%;
}
The body looks to its parent (HTML) for how to scale the dynamic property, so the HTML element needs to have its height set as well.
However, the content of the body will probably need to change dynamically. Setting min-height to 100% will accomplish this goal.
html {
height: 100%;
}
body {
height: 100%;
}
To the parent div of the page, add the following css.
position: fixed;
overflow: auto;
height: 100vh;
Try This:
[data-reactroot]
{height: 100% !important; }
Alternatively, if anything suggested above doesn't seems to be working for some reason, try using normalize.css package. It wipes all browser provided CSS and creates a fresh window for the app.
"normalize.css": "^8.0.1" //package.json (yarn add or npm install)
import "normalize.css/normalize.css"; //in app.js
Then in css file define the body height and width as 100vh & 100vw respectively.
docs: https://necolas.github.io/normalize.css/
There are a lot of answers here but none of them is working. I have tested all of them.
The best way to achieve minimum height in react js is to use the main tag inside your app and then add the minimum height for that tag.
Your App.js code should look like this.
<React.Fragment>
<Header />
<main>
<Container>
</Container>
</main>
<Footer />
</React.Fragment>
Note
You can simply remove React.Fragment if you want to use empty fragments.
then your code should look like this.
<>
<Header />
<main>
//Write your code here
</main>
<Footer />
</>
Now add CSS to your CSS file.
main {
min-height: 80vh;
}
Important
Few things you have to keep in mind.
Your header and footer or component call should be outside of the main tag. Like the code, I have shared above. I have called the header and footer outside the tag.
If you want to use routing then simply add Router above the tag.
Your code with routing and components call should look like this.
<React.Fragment>
<Router>
<Header />
<main>
<Container>
<Route path='/' component={HomeScreen} exact />
<Route path='/products' component={ProductScreen} />
<Route path='/cart' component={CartScreen} />
<Route path='/login' component={LoginScreen} />
</Container>
</main>
<Footer />
</Router>
</React.Fragment>
Related
I need to create auto resizable image components based on parent container without squeezing the image(It should maintain the image aspect ratio.) and It should be left aligned. But In react Native I have used resize mode as "contain", the image automatically gets resized but I'm not able to display the image as left aligned.
But in simple HTML & CSS I could able to achieve it simply, but the same styles not working properly in React-Native.
I need the result to be like the given example:
https://codesandbox.io/s/dark-forest-44upv
But I'm trying the same in react native:
https://codesandbox.io/s/react-native-1mu8w
Expected result got by using CSS:
<!DOCTYPE html>
<html>
<head>
<title>cell padding</title>
<style>
.gfg {
width: 600px;
height: 200px;
background-color: powderblue;
overflow: hidden;
}
img {
height: 100%;
width: auto;
}
</style>
</head>
<body>
<div class="gfg">
<img
src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS4t0Nrhw1Vboa5_AD7mqkzX36ncefzMM8Maomzofa7OWkLPkN7&s"
/>
</div>
</body>
</html>
The same in react native,but not getting the expected result.
import React, { Component } from "react";
import { Button, Image, StyleSheet, Text, View } from "react-native";
import styled from "styled-components/native";
class App extends Component {
render() {
return (
<Container>
<ImageCont
accessibilityLabel="React logo"
source={{
uri:
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS4t0Nrhw1Vboa5_AD7mqkzX36ncefzMM8Maomzofa7OWkLPkN7&s"
}}
//resizeMode="contain"
/>
</Container>
);
}
}
const Container = styled.View`
width: 600px;
height: 200px;
background-color: powderblue;
overflow: hidden;
`;
const ImageCont = styled.Image`
height: 100%;
width: auto;
`;
export default App;
Thanks in advance for your help.
<ImageCont
accessibilityLabel="React logo"
source={{
uri:
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS4t0Nrhw1Vboa5_AD7mqkzX36ncefzMM8Maomzofa7OWkLPkN7&s"
}}
style = {{flex:1}}
/>
Try giving an style of flex :1 to the child component
I am attempting to adjust the width of the react-datepicker input box and surprisingly have found little information out there and am unable to effect its width. I would just like to make the input width 100% of its containing div.
Expected behavior
The width should expand to the width of its parent container.
My react-datepicker
<div className="myContainer">
<DatePicker
className="myDatePicker"
fixedHeight
readOnly={true}
isClearable={false}
placeholderText="End date"
selected={this.props.defaultValue}
onChange={(date) => this.props.handleDateChange(date)}
/>
</div>
Expected behavior
The following should result in the myDatePicker being the same width as the parent myContainer, but the width remains unchanged.
.myContainer {
display: flex;
flex-wrap: nowrap;
flex-direction: row;
flex: 1 1 0px;
}
.myDatePicker {
width: 100%; // note: if I change this value to a fixed value (such as 500px) then the width is effected
}
Closest Alternative attempt
The closest attempt was this, but it effects the width of the popup as well, causing it to stretch beyond the length of the entire screen, so this does not work as a solution either:
.myContainer div {
width: 100%;
}
Actual behavior
The date picker remains the same length, unless a specific px value is set for the width.
Does anyone understand how to set the input width to 100% for react-datepicker?
EDIT
I believe the reason it does not work like a typical input field is because react-datepicker is an input that is embedded deeper inside other divs that have their own styling (or lackthereof)
EDIT #2: Here is a codepen showing the issue - https://codepen.io/anon/pen/bjxENG
I had the same issue and solved it thanks to Rbar's answer.
Wrap your DatePicker component with a custom container. Then assign the width to that container and its children like below:
import "./customDatePickerWidth.css";
<div className="customDatePickerWidth">
<DatePicker dateFormat="dd/MM/yyyy" />
</div>
Inside the customDatePickerWidth.css:
.customDatePickerWidth,
.customDatePickerWidth > div.react-datepicker-wrapper,
.customDatePickerWidth > div > div.react-datepicker__input-container
.customDatePickerWidth > div > div.react-datepicker__input-container input {
width: 100%;
}
I also stumbled into this issue as well. To solve this, there is a property that you can add directly to the DatePicker component which is the "wrapperClassName" and this property will allow us to directly apply classes to the "react-datepicker-wrapper".
Example:
<DatePicker wrapperClassName="datepicker" />
and then
.datepicker {
width: 100%;
}
or if you are using tailwindcss, just directly apply
<DatePicker wrapperClassName="w-full" />
Note: This will only make the wrapper to be full width, therefore you will also need to apply "width: 100%" on the datepicker component if you want the input field to occupy full width as well.
Simple solution: Add this to your css file.
.react-datepicker__input-container {
width: inherit;
}
.react-datepicker-wrapper {
width: 100%;
}
This is my html
<div class="container">
<div>
<div class="react-datepicker-wrapper">
<div class="react-datepicker__input-container">
<input class="form-control" type="text" value="">
</div>
</div>
</div>
</div>
I have used a wrapper div around the react date picker and used a specific css selector to make the wrapper divs react date picker applies around the input and the div I added to be width 100%
this is the css selector applied to a div which wraps the above snippet
.container > div,
.container > div > div.react-datepicker-wrapper,
.container > div > div > div.react-datepicker__input-container {
width: 100%;
}
The result is the input box width stretches to 100% but the pop-out date picker box stays the same width
//html file
<div className="customDatePickerWidth">
<DatePicker
placeholderText="Select Schedule Date"
/>
</div>
//css file
.customDatePickerWidth,
.customDatePickerWidth > div.react-datepicker-wrapper,
.customDatePickerWidth > div > div.react-datepicker__input-container
.customDatePickerWidth > div > div.react-datepicker__input-container input {
width: 100%;
height: 100%;
}
.react-datepicker__input-container {
width: inherit;
height: inherit;
}
.react-datepicker__input-container input {
width: inherit;
height: 100%;
}
.react-datepicker-wrapper {
width: 100%;
}
Gives the child (unnammed input) 100% while also give it's parent (__input-container) a block display.
.react-datepicker__input-container input {
display: block;
width: 100% !important;
}
just use:
<DatePicker containerStyle={{width: '100%'}}/>
To prevent the flex items from shrinking, set the flex shrink factor to 0:
.myContainer .myItem {
flex-shrink: 0;
}
.myContainer {
display: flex;
flex-wrap: nowrap;
flex-direction: row;
flex: 1 1 0px;
}
.myDatePicker {
width: 100%;
}
<div class="myContainer">
<input class="myDatePicker">
</div>
The above snippet just works so there MUST be other code interfering with css or scaffolding.
Using styled-components
import styled from 'styled-components';
const DatePickerStyled = styled.div`
/* STYLE FOR WITH */
.react-datepicker-wrapper {
width: 100%;
}
`;
encloses the component
<DatePickerStyled>
<DatePicker dateFormat="dd/MM/yyyy" />
</DatePickerStyled>
I just passed a className to the component:
<DatePicker className='date-input-field' />
Here's how I set the width:
.date-input-field {
max-width: 7rem;
}
Another option:
Remove all styling there is by default.
Introduce the width of 100%
My React datepicker:
<div className="col-3">
<DatePicker
selected={st}
onChange={(date: Date) => checkAndChangeStartTime(date)}
showTimeSelect
showTimeSelectOnly
timeIntervals={5}
timeCaption="Time"
dateFormat="HH:mm"
timeFormat="HH:mm"
/>
</div>
The CSS to make this option work:
.react-datepicker-wrapper>.react-datepicker__input-container input {
all: unset !important;
width: 100% !important;
}
This forces the div to be 100% width, but requires you to start styling the element the beginning.
Hey I create Ember application , And I try to set Sticky Footer.
I try to do this by this tutorial Sticky Footer On CSS-Tricks , Cause it's work for me once.
But with Ember its dosen't work
My css:
.mainFooter {
height:100px;
color:white;
background-color: #0c2635;
text-align:center;
}
.wrapper {
min-height: 100%;
margin-bottom: -100px;
}
.wrapper:after {
content: "";
display: block;
}
.mainFooter, .wrapper:after {
height: 100px;
}
My HTML:
<footer class="mainFooter">
SOME TEXT
</footer>
As I said, it's dosent work.
I watch the source code via the Inspector and I saw that Ember added its own wrapper to content the I put in the application.hbs file, this wrapper have a class named ember-view so I try to do:
.ember-view {
min-height: 100%;
}
But it's dosent work either, the footer displayed in the middle of the page.
Someone maybe try this and successid?
I would like to know about a solution to this problem.
I don't know how to fake an Ember app in jsfiddle/codeopen so I upload the app to my server, url: http://drawyourgif.pe.hu/dist/
EDIT
According to the solution that kumkanillam sugest I did so:
Application.hbs:
{{outlet "modal"}}
{{partial "header"}}
<div id="gif" class="wrapper">
{{outlet}}
</div>
{{partial "footer"}}
app.js
App = Ember.Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
rootElement: '#gif',
Resolver
});
And I get this error in the console:
ember.debug.js:43272Uncaught TypeError: Cannot read property 'tagName' of undefined
What I did wrong?
.ember-view will be included for all ember component by default so it's not good to apply css property for this class.
there may be many ways but the below should help.
You can wrap your application.hbs to render inside your page-wrap div.
for this you need to include the below line in
index.html
<div id="app-name" class="wrapper">
{{content-for "body"}}
</div>
application.hbs
<h1> Content </h1>
{{outlet}}
<div id="footer">
<p>I'm the Sticky Footer. inside application.hbs</p>
</div>
Configure rootElement in app.js. that will force entire app to include it in app-name div.
app.js
App = Ember.Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
rootElement: '#app-name',
Resolver
});
app.css
#wrapper {
min-height: 100%;
overflow: auto;
}
#footer {
position: absolute;
bottom: -3px;
left: 2px;
right: 2px;
height: 50px;
background-color: rgba(0, 0, 0, 0.8);
color: #fff;
}
Final Update:
You don't need to change anything in app.js. just look at the sample twiddle. I think this will help you
SAMPLE TWIDDLE
Here is a solution that uses flexbox. You may not want to use flexbox because you're unfamiliar with it, but I'll submit this answer for later google searches.
Here's a codepen with very little content in the main body: http://codepen.io/anon/pen/KgXgjV
Here's the same css with much more content in the main area: http://codepen.io/anon/pen/dpVpBK
Here is an example of why position: absolute doesn't work: https://ember-twiddle.com/f620502b8172f4181c9d58503e02e39c?openFiles=templates.application.hbs%2C
HTML
<html>
<body>
<div id="root" class="ember-application">
<div id="ember332" class="ember-view">
<div class='main-content'>
<h1>Welcome to Ember Twiddle</h1>
<br />
<p>
this page has very little content
</p>
</div>
<div id="footer">
<p>I'm the Sticky Footer. inside application.hbs</p>
</div>
</div>
</div>
</body>
</html>
CSS
/* this is just to reset codepen */
/* probably not necessary on ember */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* end reset */
html, body, #root {
height: 100%;
}
.ember-view {
display: flex;
flex-direction: column;
min-height: 100vh;
background: lightblue;
}
.main-content {
flex: 1;
}
#footer {
width: 100%;
height: 50px;
background-color: grey;
}
I have the following configuration in a simple html file:
* {
box-sizing: border-box;
}
html, body {
height: 100%;
min-height: 100%;
margin: 0;
}
section {
display: block;
width: 100%;
min-height: 100%;
padding: 1em
}
.b1 {
background: #2AC56D
}
.b2 {
background: #fae10c
}
.b3 {
background: #03a9f4
}
<section class="b1">1
</section>
<section class="b2">2
</section>
<section class="b3">3
</section>
Then I try to use AngularJS Routing in the following way: the section elements go into a template called template.html like this:
<section class="b1">1
</section>
<section class="b2">2
</section>
<section class="b3">3
</section>
And I add to the main file the AngularJS, the ng-route dependencies and the following script like this:
<script src="js/angular.min.js"></script>
<script src="js/angular-route.min.js"></script>
<script>
var app = angular.module('app', ['ngRoute']);
app.config(function($routeProvider, $locationProvider) {
$routeProvider.when('/', {
templateUrl: 'template.html'
}).otherwise({
redirectTo: '/'
});
});
</script>
</head>
<body data-ng-app="app">
<div data-ng-view>
</div>
</body>
It is working on the scripting part, but the section elements are no longer full height and look like this.
What is really the issue and, more important, how can I correct it? What I really need is to have some div's or section's at least full screen height.
Thank you.
Hmmm, To make height: 100%; work properly, you need to set in its parent div too.
Suppose this html:
<div id="main">
<section>1</section>
</div>
Then just applying 100% height in section won't work. You need to set fixed height for the parent element. So, use:
#main{
height: 100%;
}
You already set 100% height in html,body tag that's good.
So, in your case, apply like this:
div[data-ng-view]{
height: 100%;
}
The bootstrap documentation on that topic is a little confusing to me. I want to achieve similar behaviour like in the docs with the affix navbar: The navbar is below a paragraph / page heading, and upon scrolling down it should first scroll along until reaching the top of the page, and then stick there fixed for further scrolldowns.
As jsFiddle does not work with the navbar concept, I've set up a separate page for usage as a minimal example: http://i08fs1.ira.uka.de/~s_drr/navbar.html
I use this as my navbar:
<div class="navbar affix-top" data-spy="affix" data-offset-top="50">
<div class="navbar-inner">
<div class="container">
<div class="span12">
<a class="brand" href="#">My Brand</a>
This is my navbar.
</div>
</div> <!-- container -->
</div> <!-- navbar-inner -->
</div> <!-- navbar -->
I thinkg i would want data-offset-top to be of value 0 (since the bar should "stick" to the very top" but with 50 there is at least some effect watchable.
If also put the javascript code in place:
<script>
$(document).ready (function (){
$(".navbar").affix ();
});
</script>
Any help appreciated.
I was having a similar problem, and I believe I found an improved solution.
Don't bother specifying data-offset-top in your HTML. Instead, specify it when you call .affix():
$('#nav').affix({
offset: { top: $('#nav').offset().top }
});
The advantage here is that you can change the layout of your site without needing to update the data-offset-top attribute. Since this uses the actual computed position of the element, it also prevents inconsistencies with browsers that render the element at a slightly different position.
You will still need to clamp the element to the top with CSS. Furthermore, I had to set width: 100% on the nav element since .nav elements with position: fixed misbehave for some reason:
#nav.affix {
position: fixed;
top: 0px;
width: 100%;
}
One last thing: When an affixed element becomes fixed, its element no longer takes up space on the page, resulting in the elements below it to "jump". To prevent this ugliness, I wrap the navbar in a div whose height I set to be equal to the navbar at runtime:
<div id="nav-wrapper">
<div id="nav" class="navbar">
<!-- ... -->
</div>
</div>
.
$('#nav-wrapper').height($("#nav").height());
Here's the obligatory jsFiddle to see it in action.
Just implemented this for the first time, and here's what I've found.
The data-offset-top value is the amount of pixels that you must scroll in order for the affixing effect to take place. In your case, once 50px is scrolled, the class on your item is changed from .affix-top to .affix. You'd probably want to set data-offset-top to about 130px in your use case.
Once this class change occurs, you must position your element in css by styling the positioning for class .affix. Bootstrap 2.1 already defines .affix as position: fixed; so all you need to do is add your own position values.
Example:
.affix {
position: fixed;
top: 20px;
left: 0px;
}
To fix this very issue I have modified the affix plugin to emit a jQuery event when an object is affixed or unaffixed.
Here is the pull request: https://github.com/twitter/bootstrap/pull/4712
And the code: https://github.com/corbinu/bootstrap/blob/master/js/bootstrap-affix.js
And then do this to attach the navbar:
<script type="text/javascript">
$(function(){
$('#navbar').on('affixed', function () {
$('#navbar').addClass('navbar-fixed-top')
});
$('#navbar').on('unaffixed', function () {
$('#navbar').removeClass('navbar-fixed-top')
});
});
</script>
You need to remove .affix() from your script.
Bootstrap gives the option of accomplishing things either via data-attributes or straight JavaScript most of the time.
I've got this from the twitterbootstrap's source code and it's working pretty well:
HTML:
<div class="row">
<div class="span3 bs-docs-sidebar">
<ul id="navbar" class="nav nav-list bs-docs-sidenav">
...
</ul>
</div>
</div>
CSS:
.bs-docs-sidenav {
max-height: 340px;
overflow-y: scroll;
}
.affix {
position: fixed;
top: 50px;
width: 240px;
}
JS:
$(document).ready(function(){
var $window = $(window);
setTimeout(function () {
$('.bs-docs-sidenav').affix({
offset: {
top: function (){
return $window.width() <= 980 ? 290 : 210
}
}
})
}, 100);
});
You just need to remove the script. Here is my example:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.0/js/bootstrap.min.js"></script>
<style>
#content {
width: 800px;
height: 2000px;
background: #f5f5f5;
margin: 0 auto;
}
.menu {
background: #ccc;
width: 200px;
height: 400px;
float: left;
}
.affix {
position: fixed;
top: 20px;
left: auto;
right: auto;
}
</style>
</head>
<body>
<div id="content">
<div style="height: 200px"></div>
<div class="affix-top" data-spy="affix" data-offset-top="180">
<div class="menu">AFFIX BAR</div>
</div>
</div>
</body>
</html>
Thanks to namuol and Dave Kiss for the solution.
In my case I had a tiny problem with navbar height and width when I used afflix and collapse plugins together. The problem with width can be easily solved inheriting it from parent element (container in my case). Also I could manage to make it collapsing smoothly with a bit of javascript (coffeescript actually). The trick is to set wrapper height to auto before collapse toggle occurs and fix it back after.
Markup (haml):
#wrapper
#navbar.navbar
.navbar-inner
%a.btn.btn-navbar.btn-collapse
%span.icon-bar
%span.icon-bar
%span.icon-bar
#menu.nav-collapse
-# Menu goes here
CSS:
#wrapper {
width: inherit;
}
#navbar {
&.affix {
top: 0;
width: inherit;
}
}
Coffeescript:
class Navigation
#initialize: ->
#navbar = $('#navbar')
#menu = $('#menu')
#wrapper = $('#wrapper')
#navbar.affix({offset: #navbar.position()})
#adjustWrapperHeight(#navbar.height())
#navbar.find('a.btn-collapse').on 'click', () => #collapse()
#menu.on 'shown', () => #adjustWrapperHeight(#navbar.height())
#menu.on 'hidden', () => #adjustWrapperHeight(#navbar.height())
#collapse: ->
#adjustWrapperHeight("auto")
#menu.collapse('toggle')
#adjustWrapperHeight: (height) ->
#wrapper.css("height", height)
$ ->
Navigation.initialize()
My solution for attach the navbar :
function affixnolag(){
$navbar = $('#navbar');
if($navbar.length < 1)
return false;
h_obj = $navbar.height();
$navbar
.on('affixed', function(){
$navbar.after('<div id="nvfix_tmp" style="height:'+h_obj+'px">');
})
.on('unaffixed', function(){
if($('#nvfix_tmp').length > 0)
$('#nvfix_tmp').remove();
});
}
Similar to the accepted answer, you can also do something like the following to do everything in one go:
$('#nav').affix({
offset: { top: $('#nav').offset().top }
}).wrap(function() {
return $('<div></div>', {
height: $(this).outerHeight()
});
});
This not only invokes the affix plugin, but will also wrap the affixed element in a div which will maintian the original height of the navbar.