Vuetify navbar (v-app-bar) overlap scrollbar - css

The same problem as this post except it is Vuetify.
Is there any solution that use provided API? CSS would be the last option I choose.
codepen demo
<template>
<v-app-bar app dark absolute class="navbar-bg" >
<v-app-bar-nav-icon #click="toggleSidebar" />
<v-toolbar-title>Homepage</v-toolbar-title>
</v-app-bar>
</template>

Currently, there's no a single prop in API.
But you may help yourself a lot with a built-in vuetify classes and directives.
First of all, you (sadly) need to write some CSS to manually disable initial page scrolling:
html {
overflow-y: hidden;
}
.scrollable {
overflow-y: scroll;
}
Then you need to add <v-main> component to your application with scrollable pt-0 mt-16 classes and wrap all of your future app components into it. This classes will adjust the padding from the default <v-app-bar> and enable scrolling directly in <v-main>.
Finally, you should add v-resize directive to <v-main> to automatically recalculate your page size when user will resize a page:
<v-main class="scrollable pt-0 mt-16" v-resize="onResize">
...your application data...
</v-main>
...
methods: {
onResize() {
//64px is v-app-bar height in your case
document.querySelector(".scrollable").style.height = (window.innerHeight - 64) + 'px';
}
},
That's it. You may then create your custom component to wrap <v-main> and forget about such manipulations.
Codepen link with an example

Related

Center spinner in viewport on bootstrap overlay

I'm using the bootstrap-vue overlay on a page that has long content scrolled via the browser window.
<b-overlay :show="loading">
The overlay correctly covers all of the content, even the part below the viewport, but the overlay's built-in spinner is centered on the content rather than the viewport, so the spinner ends up near or below the bottom of the viewport when the content is long enough.
I've tried custom content via a slot, like this...
<b-overlay :show="loading">
<template v-slot:overlay>
<div style="???" class="text-center">
<p style="???">Make me a spinner and center me on the viewport</p>
<b-button
</div>
</template>
...with dozens of ideas for style="???", including position:absolute with different tops, including top=50vh, including !important strewn around, etc., but the content doesn't budge.
// Note that this snippet doesn't run, because I don't see a way to get
// bootstrap-vue via CDN
var app = new Vue({
el: '#app',
data: function() {
return {
message: 'Hello Vue!',
messages: []
}
},
mounted() {
for (let i=0; i<50; i++)
this.messages.push(i)
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<b-overlay :show="true">
{{ message }}
<!-- long content below extends the overlay size -->
<!-- this moves the spinner down and off the viewport -->
<ul>
<li v-for="m in messages" :key="m">{{m}}</li>
</ul>
</b-overlay>
</div>
I think key to solving this is finding the CSS selector that allows me to change the spinner's position to "fixed" as opposed to "absolute" which seems to be what bootstrap generates.
To get spinner on center of screen you need to make it as direct child of body.
If it is nested it will have restrict area inside immediate parents area.
Try to add that separately or once your DOM ready detach overlay and append to body tag.
I ran into the same issue. Adding this line of CSS on the component resolved it for me:
<style>
.position-absolute {
position: fixed !important;
}
</style>
Note: make sure to not include the scoped keyword in your <style> tag, as this will not work for Bootstrap classes.

I want to apply a background image to the body of only one component

I am very new to React, so apologies for the mistakes in advance.
In my React app, say I have 2 components and as the CSS styles are global, it picks up CSS styles from all the files.
However, I wish to add a full background image to one of the components which I was able to achieve by using this code in my CSS file:
body {
background-image: url("../image.jpg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
The problem is that the same image is also being applied to another component. I read a few answers and found that I can use ComponentDidMount hook and add the image to the body tag there. I tried that, but it doesn't show anything.
componentDidMount() {
document.body.style.backgroundImage = "url('../image.jpg')";
document.body.style.backgroundPosition = "center";
document.body.style.backgroundRepeat = "no-repeat";
document.body.style.backgroundSize = "cover";
}
EDIT
I realized I had the wrong wording for the question. What I mean to say is that I have two pages in React. For one of the pages, I want a full background image. However, because CSS styles are global, the background image is getting applied to all the pages.
You can use inline styling or specific styling by assigning a specific class or ID to the top element of one component.
INLINE STYLING Example:
// If Background variable has url to the background image.
const style = {
backgroundImage: `url(${Background})`
}
// in component use that inline style
return (
<div style={style}></div>
);
IF YOU WANT TO WORK with body only...
then add a class to body on component A mount and remove the class on component B mount. And attach the background property to the class.
A component usually return some jsx and in most cases a div. In other to apply a css to a single component I mean the jsx the component is rendering. you should define a css class, that apply a background image to the div the component is rendering and make the height of the div the window height. you can do this via inline css all
const MainDiv =()=>(
<div classname="testClass">
This will show background image in the covering the entire body
//Other content of your page can be added here like the rest of your page contents
<header>
This is my blog post
</header>
<nav>
this is my navbar
</nav>
</div>
);
ReactDOM.render(<MainDiv />, document.getElementById("root"));
.testClass{
backgroundImage :"url('../image.jpg')";
backgroundPosition :"center";
backgroundRepeat : "no-repeat";
background-size : "cover";
width: 100%;
height: 100vh
}

Set full-width on input

How do I set full width on input elements inside a radio group?
I'm using the following setup to create two options (user can either upload a file or specify a URL):
<v-radio-group v-model="photo_mode">
<v-layout row align-baseline>
<v-radio value="file" />
<v-file-input v-model="eitem.photo" class="mr-4 mt-0" :disabled="photo_mode=='url'" />
</v-layout>
<v-layout row align-baseline>
<v-radio value="url" />
<v-text-field v-model="eitem.photo_url" class="mr-4 mt-0" :disabled="photo_mode=='file'" />
</v-layout>
</v-radio-group>
The looks fine except that both v-file-input and v-text-field are not as wide as the container. Here is a snapshot:
As you see, the v-text-field above the radio group (Details field) is correctly showing full-width, but the two inputs inside the radio group are not. What can I do to fix this?
Found the solution. This is a bug in Vue. Already reported here. The solution is to simply add the following CSS in your App.vue:
<style>
.v-input--selection-controls .v-input__control{
width: 100%;
}
</style>
Make sure the style section is not marked with scoped keyword.
I found that I also needed to set the style of v-label too, in order for this workaround to function properly. Also I used scoped css locally in the component:
.radio-group-full-width >>> .v-input__control {
width: 100%
}
.radio-group-full-width >>> .v-label {
width: 100%
}
So in the template:
<v-radio-group class="radio-group-full-width">

Styling from separate CSS files not applied with new components

I have been trying to build a small project with React for the past few days and all went great until today. For some reason, no CSS is applied to new components! All the CSS that worked before is still up and running but if I'd add something like a div in between an already existing div, the new div will not pick up any CSS!
Example:
<div className="DivStyle"> // Styling applied!
<div className="DivStyle"> </div> // Styling completely ignored!
<div>
It is probably worth mentioning that I am still able to style the components inline.
Also, looking at the sources in Chrome, the styles are uploaded!
Here is my concrete example:
import '../styles/drawers.css';
class BottomFilterDrawer extends React.Component<IBottomFilterDrawerProps, IBottomFilterDrawerState> {
...
public render() {
return(
<Drawer
open={this.state.isOpen}
anchor="bottom"
// tslint:disable-next-line jsx-no-lambda
onClose={() => this.toggleDrawer(false)}>
<div className="BottomDrawerContainer" style={{margin: "10px"}}> // Styling for "BottomDrawerContainer" class not applied!
...
</div>
</Drawer>
);
}
}
The CSS file:
#BottomDrawerContainer {
margin: 10px;
}
I am certain that the import path is correct, Typescript wouldn't even let me run it if it weren't.
You are applying css for class not for id. So your css must be like below.
.BottomDrawerContainer {
margin: 10px;
}
if you want to apply for inner div.
.DivStyle .DivStyle {
//style for inner div
}
do not use again same id, React create error and if show any error first you solve error otherwise browser not show anything

Applying CSS stylesheet only to active component

I'm working on a ReactJS app that has a header at the top, a menu on the left, and the "frame" in the middle is where routes and their corresponding components are loaded. I want to be able to apply a CSS stylesheet to specific components only when they are loaded. I also don't want them applied all the time or to the top header or left menu.
My expectation was that adding import 'custom.css'; to a specific component would only apply the stylesheet's styles to that component and it's children when the route is active. Instead, it applies it to the entire page even when the route/component are not loaded.
I understand that an alternative approach is styled components, but, for my use-case, a design company is supplying a stylesheet (which should remain unchanged) that we need to consume only for the sub-module I'm working on and I don't want its styles to affect the rest of the app.
How can I have a stylesheet only applied to my active route/component?
Use simple CSS technique. Suppose you have two components with different css files (say about.css and contact.css). Now consider your both CSS file have one common class with different style properties, like:
about.css
.container{
max-width: 400px;
}
contact.css
.container{
max-width: 500px;
}
Yes in ReactJS both the CSS files will load at the same time and will override any one of the style. so to solve this problem add class to differentiate this styles, like:
about.css
.about-component.container{
max-width: 400px;
}
contact.css
.contact-component.container{
max-width: 500px;
}
If you want apply only when the component is mounted, you can use the lifecycle.
The follow example is based in the idea you are using sass, React, sass-node and have the loaders into webpack.
<pre>
import React from 'react';
import './styles.scss';
class MyComponent {
constructor(props) {
super(props);
this.state = { className: '' }
}
componentDidMount() {
this.setState({
className: 'myOwnClass'
});
}
render(){
return (
<div className={this.state.className}>This is a example</div>
);
}
}
export default myComponent;
</pre>
To be able to only call that specific CSS when you need it you can use CSS Modules. You may need to update your version of react.
When saving your CSS file save it with a ".module.css" eg. "styles.module.css". The CSS in these files can only be used and accessed by hte components where are they are imported. As stated in a tutorial from W3Schools.
Let's say this is your CSS code in styles.module.css:
.container {
color: white;
}
.cont-child {
background-color: red;
}
Then in your JS file you can import the CSS file like this if the JS and CSS files are in the same directory. Make sure you point to the correct path.
import styles from './styles.module.css'
Then in your HTML section you can use it like this:
class Home extends React.Component {
render() {
return(
<main className={ styles.container } >
<div className={ styles["cont-child"]} >
Some div text about something...
</div>
</main>
);
}
}
I currently use both ways to access the selectors, since the styles variable acts like an object. I placed both of them here because the second option is capable of fetching selectors named like "btn-active". Which comes in handy in some situations. Camelcasing is considered cleaner though.
Please note: I originally posted this answer as a reply to a similar question here React CSS - how to apply CSS to specific pages only
I want to be able to apply a CSS stylesheet to specific components
only when they are loaded.
Why not apply the styles inline via React.js?
Step 1. Create the style object for the component:
var componentOneStyle = {
color: 'white',
backgroundColor: 'red'
};
Step 2. Populate the component's style attribute with the style object:
ReactDOM.render(<div style={componentOneStyle}>This is Component One</div>, mountNode);

Resources