navbar-fixed-top show content behind Navbar - react-bootstrap

How do you prevent the content from floating behind the Navbar when scrolling?
<Navbar className="navbar-form navbar-fixed-top" responsive collapseable brand='x' inverse toggleNavKey={1} onClick={this.handleMouseDown}>
Or is it in:
<Nav className="navigation"..
Thanks

Add a custom class to your navbar component, say, sticky-nav. Define the following CSS properties on it:
.sticky-nav {
position: sticky;
top: 0;
}
This will make your navbar stick to the top and will automatically adjust the height of its following DOM elements. You can read more about the sticky property on MDN.

As Scrotch said adding:
<Navbar style={{backgroundColor: "#071740", position: "sticky"}} variant="dark" fixed="top">
worked for me, I did it inline but putting in a separate CSS file should work as well. This is the only thing that's worked so far for me.
NB: I'm using "react-bootstrap": "^1.0.0-beta.16"

I was running into this too. I found the following (baseline bootstrap) page that shows a fixed navbar and has the main page showing up properly below it. It seems to be a function of the css that they are using. Specifically:
padding-top: 70px;
I added
body {
padding-top: 70px;
}
to my css file, and it seems to be working. Obviously mileage may vary, not applicable in all territories, etc. I am going to need to test it further for myself, but that might get you started.

In order to get responsive padding-top for body you may use sth. like this (ES6 example):
import ReactDOM from 'react-dom';
import React from 'react';
import { Navbar, Nav, NavItem } from 'react-bootstrap';
export default class Template extends React.Component {
constructor(props) {
super(props);
this.state = { navHeight: 50 };
this.handleResize = this.handleResize.bind(this);
}
handleResize(e = null) {
this.setState({ navHeight: ReactDOM.findDOMNode(this._navbar).offsetHeight });
}
componentDidMount() {
window.addEventListener('resize', this.handleResize);
this.handleResize();
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}
render() {
return (
<body style={{paddingTop: this.state.navHeight}}>
<Navbar ref={(e) => this._navbar = e} fixedTop>
<Navbar.Header>
<Navbar.Brand>
<Link to="/">Some title</Link>
</Navbar.Brand>
</Navbar.Header>
<Nav>
<NavItem eventKey={1} href="/link1">Link1</NavItem>
<NavItem eventKey={2} href="/link2">Link2</NavItem>
</Nav>
</Navbar>
<main>
{this.props.children}
</main>
</body>
);
}
}
Template.propTypes = {
navHeight: React.PropTypes.number,
children: React.PropTypes.object,
};
This way your <body> padding-top will always fit your navbar height even after adding more links in mobile view.
I also assume that base height is 50px (see the constructor) but it shouldn't matter as long as you call this.handleResize() in componentDidMount().

There is also the option to specify sticky-top which basically implements the solution of using position:sticky that others have suggested (see documentation).
So in your example you could just specify sticky-top instead of fixed-top as a className, and it satisfies your requirements.

react-bootstrap provides position utilities.
<Navbar sticky="top">
react-bootstrap documentation
However in-page anchor does not work properly, and position can be under the navbar after jump from a link.
I also use this custom css to fix the issue.
*[id]:before {
display: block;
content: " ";
margin-top: -75px;
height: 75px;
visibility: hidden;
}
Reference

I came across the same problem. Wanting to stay within bootstrap and avoid custom css I tried adding class 'position-sticky', which gave me a left-shifted navbar. Apparently, for whatever reason, the navbar has a negative padding, so adding 'ps-0' to the class list fixed it.
<Navbar
fixed={'top'}
className={'position-sticky ps-0'}
>

for anyone using tailwind use sticky as a property in the top div of your navbar
<div className="sticky"> navbar-content </div>

Related

How to do page transitions with svelte/sapper

I want to realize a simple page (route) transition in Sapper. Something that is easily achievable with Nuxt for example. Does anyone have an idea how to realize that with Sapper?
I already wrapped my page content into a div with a transition:fade directive. This works. Yet, the two pages transition at the same time, meaning while one page transitions out the other one already transitions in. It would be great if someone pointed me in the right direction. Thanks!
Let me just start of by saying I don't know if this is the most effective way to do it. This is the way I solved it and it works great for me.
I first made my own custom variation of the 'fade' transition and put it in 'components/pageFade.js'
import { sineOut } from "svelte/easing";
let duration = 250;
let delay = duration;
let delayZero = 0;
export const fadeIn = _ => ({
duration,
delay,
easing: sineOut,
css: t => `opacity: ${t}`
});
export const fadeOut = _ => ({
duration,
delay: delayZero,
easing: sineOut,
css: t => `opacity: ${t}`
});
The delayZero variable is there because for some reason it won't take '0' directly and will break.
The duration variable is the length of the fade in milliseconds
Then for all files I wanted to have this transition on I did the following:
<script>
import { fadeIn, fadeOut } from "../components/pageFade";
// All your other JS goes here
</script>
<style>
/* Styles go here */
</style>
<main in:fadeIn out:fadeOut>
<!-- All the normal HTML goes here -->
</main>
I would then use that as a template on almost every single one of the pages, which seems like a lot but it's not too bad.
Hope it helps and let me know if you have any other questions!
Max
If you want to include transition in _layout.svelte and don't need to include them in every route here is an alternative.
Here is a simple fly in/out from top transition.
<!-- src/component/PageTransitions.svelte -->
<script>
import { fly } from 'svelte/transition';
export let refresh = '';
</script>
{#key refresh}
<div
in:fly="{{ y: -50, duration: 250, delay: 300 }}"
out:fly="{{ y: -50, duration: 250 }}"
>
<slot/>
</div>
{/key}
And here is the Sapper layout component
<!-- src/routes/_layout.svelte for Sapper -->
<script>
import { page } from '$app/stores'; // svelte#next
import Nav from '../components/Nav';
import PageTransitions from '../components/PageTransitions';
export let segment;
</script>
<Nav {segment}/>
<PageTransitions refresh={segment}>
<slot/>
</PageTransitions>
And here is the SvelteKit (svelte#next) layout component
<!-- src/routes/$layout.svelte for Svelte#next -->
<script>
import { page } from '$app/stores'; // svelte#next
import Nav from '../components/Nav';
import PageTransitions from '../components/PageTransitions';
</script>
<Nav segment={$page.path}/>
<PageTransitions refresh={$page.path}>
<slot/>
</PageTransitions>
And for completeness here is a simple Nav component
<!-- src/component/Nav.svelte -->
<script>
export let segment;
</script>
<style>
a {
text-decoration: none;
}
.current {
text-decoration: underline;
}
</style>
<div>
<a href="/" class='{segment === undefined ? "current" : ""}'>Home</a>
<a href="/about" class='{segment === "about" ? "current" : ""}'>About</a>
</div>
NOTES:
We make the component reactive by creating a refresh prop and using key directive which means that when the key changes, svelte removes the component and adds a new one, therefore triggering the transition.
In the layout component we pass the segment (route) as refresh prop and therefore the refresh key changes as the route changes.
Here is a demo of the sample code above and the github repo
FYI #max-larsson, from your code, fadeIn is defined as a function which needs no arguments and returns an object having a duration property equal to the value of the duration variable at this scope. same with delay. Note easing is defined as the name, with the value of sineOut.
This may be your issue if you just tried to put a literal 0 where delay was. I see you tried making delayZero, but used it likely in a different way than you intended. You probably meant to write this:
export const fadeOut = _ => ({
duration,
delay: 0,
easing: sineOut,
css: t => `opacity: ${t}`
});
When I tried this, it works just fine for me. Thanks for sharing your example.
I guess Svelte Kit has changed since #GiorgosK answer, because I cannot make it work with the code in his answer.
But fortunately, his github repo has been update with the solution, thanks !
The page.path properties much be used in module context
This is my version without a specific component for page transition :
<!-- src/route/__layout.svelte -->
<script context="module">
export const load = async ({ page }) => ({
props: {
key: page.path,
},
});
</script>
<script>
import { fly } from "svelte/transition";
export let key;
</script>
<nav>
foo
bar
</nav>
{#key key}
<div
in:fly={{ x: 50, duration: 2500 }}
out:fly={{ y: -50, duration: 2500 }}
>
<slot />
</div>
{/key}
Maybe #GiorgosK can share some insight about that change.

Ionic 2 <ion-content> disable scroll

I've tried several methods to disable scroll, including using CSS position: fixed, attribute overflow-scroll="false" and etc, but all methods failed.
When I swipe down, the buttons will go up and while I swipe up the buttons will go down, like bouncing effect.
May I know any solutions to this issue? Thank you very very much.
Tested with ionic 3 (should work on ionic 2):
<ion-content no-bounce></ion-content>
I solved same problem using css. (Ionıc 3.6)
Step1: In ion-content add a new class :
<ion-content class="no-scroll">
Step2: In your CSS add the code below :
.no-scroll .scroll-content{
overflow: hidden;
}
The ion-content has a class called 'scroll-content'.
With that in mind, go to your app.css, inside the src/app and add:
app.css:
.scroll-content{overflow-y: hidden;}
That should leave your ion-content with no scroll, but I'd rather user:
app.css:
.scroll-content{overflow-y: auto;}
since this allows the scroll-content only if the page content overflows the ion-content.
This works in ionic 5:
ion-content {
--overflow: hidden;
}
<ion-content scroll-y="false">
For disable scroll in ion-content can use setScrollDisabled() method. You should follow steps below.
In hello.ts
import { app } from 'ionic-angular';
public class HelloPage
{
constructor(private app: App) {};
ngAfterViewInit(){
this.app.setScrollDisabled(true);
}
}
If you don't want the scroll you may also don't need the ion-content itself, in my status for example I want to use the ion-grid directly.
<!-- my-page.ts >
<ion-header>.......</ion-header>
<ion-grid class="has-header fixed-content">
</ion-grid>
and I added some scss for the has-header class:
ion-app {
&.md {
.has-header {
margin-top: $toolbar-md-height;
}
}
&.wp {
.has-header {
margin-top: $toolbar-wp-height;
}
}
&.ios {
.has-header {
margin-top: $toolbar-ios-height;
}
}
}
Content is placed in the scrollable area if provided without a slot. To show a fixed content add slot="fixed".
<ion-content>
<div slot="fixed">
</div>
</ion-content>
As iflagri posted in this issue and #shaneparsons pointed in the comments, using
<ion-content padding>
<div ion-fixed>
Your content here...
</div>
</ion-content>
Solve the problem.
Hope it help!
If you want to disable the content scrolling you can use
<ion-content [scrollY]="false" >
https://ionicframework.com/docs/api/content
<ion-content [attr.noScroll]="shouldScroll"></ion-content>
// scss file:
[noScroll] {
overflow: hidden;
}
Surprisingly, no-bounce attribute did work on my previous project and is not working on a new project that I am currently working on.
I tried #rodrigo-chave's solution with ion-fixed. It solved the scrolling problem, but made my content small (as if was zoomed out). Adding 100% CSS width and height properties fixed it.
<ion-content no-bounce>
<div ion-fixed style="height: 100%; width: 100%">
...
</div>
</ion-content>

Animate css creates an transparent field over divs

I'm using animate.css to add some transistions to my meteor app. However, there is this problem that animate.css creates an almost transparant overlay over my buttons/images etc.
I have a main div where the animate.css class is added depending on changing page views etc. Very simplified this is my HTML.
<body>
<header class="header></header>
<div class="animate-holder {{animated class}}>
<div class="class1></div>
<div class="class2></div>
</div>
</body>
From what I've tested this will happen all the time and it doesn't matter how I use transistions. Is there a simple way to NOT have this overlay?
EDIT:
I can hack it like this, but this is very very ugly. But maybe it creates more insight into the problem:
Template.DetailsSubmit.rendered = function() {
Meteor.setTimeout(function() {
var classes = $('div.animated').attr('class');
$('div.animated').removeClass(classes);
}, 1000)
}
You can make this specific div clickable through using the very useful (and not famous enough) pointer-events css property:
div.animated {
pointer-events: none;
}

What is best practice for handling resize events in a polymer element?

I'm trying to create a "Viewport" type element extended from a Canvas element. I intended for it to fill the parent container, but that seems not very trivial.
The canvas element does not work with style="width:100%; height:100%" (it will revert to a default value of 300x150 pixels if the special Canvas width and the height attributes are not set, or it will go to 100x100 pixels if I try to set those attributes to "100%". This leaves me with the task of manually setting the width of the canvas element according to the size of the parent element. However I am at a loss when trying to figure out a way to access a resize event I could add a handler to from the perspective of the custom element. I don't seem to get access to window.on.resize from anywhere within the custom element. Do I have to do this from the outside?
Here is an example polymer element definition:
<polymer-element name="canvas-viewport">
<template>
<style>
#host{
:scope {
margin:0px;
padding:0px;
display:block;
position:relative;
width:100%;
height:100%;
background:limegreen;
overflow:visible;
border:0;
}
}
div {
border:0;
margin:0px;
padding:0px;
width:100%;
height:100%;
}
</style>
<div id="container">
<canvas width="{{wpWidth}}" height="{{wpHeight}}" id="theCanvas"></canvas>
</div>
</template>
<script type="application/dart" src="canvas_viewport.dart"></script>
</polymer-element>
Here is some dart code in the accompanying polymer class definition for trying to handle the resize that I made based on a suggested solution to this question.
#override
void attached() {
super.attached();
viewPortContainer = shadowRoot.querySelector("#container");
window.onResize.listen(resizecontainer);
}
void resizecontainer(Event e){
wpWidth = viewPortContainer.clientWidth;
wpHeight = viewPortContainer.clientHeight;
print("resizing Width:$wpWidth , Height:$wpHeight ");
}
However this results in a bug where the height grows by three pixels on each resize event, even though margins and paddings are set to zero.
OnResize works for me inside a custom element.
#override
void attached() {
super.attached();
window.onResize.listen((e) {
print(e.currentTarget.innerWidth);
});
}
This is how I will achieve this in Polymer.
connectedCallback() {
super.connectedCallback();
this._onResize = this.onResize.bind(this);
window.addEventListener("resize", this._onResize);
}
onResize(e) {
console.log('width', e.currentTarget.innerWidth);
}
disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener("resize", this._onResize);
}

How can I remove a zen-grid-item mixin declared in a previous media query?

I've been using Zen Grids for responsive layouts for a while now, and somehow never came across this. I've referenced the documentation, but for the life of me cannot figure out how to do something which should be relatively simple.
I have a block which I set on the grid, such as:
<div class="container">
<div class="item">
</div>
</div>
==========
.container {
#include zen-grid-container();
}
.item {
#include zen-grid-item(1, 1);
}
I then have a media query where, for whatever reason, I need to remove the item from the grid completely:
#media screen and (min-width:50em) {
.item {
???
}
}
To be clear, I'm not looking to re-declare the item to a different col-width/position, I just want to remove the mixin from being called completely. I know I can just reset the CSS manually, but was wondering if there was a better way from any Zen Grid ninjas.
Thanks!
Have you tried to just use
.item {
display: none;
}
in your media query? That should hide it and probably remove the spacing it took up as well.

Resources