Global styles for specific pages in next js - javascript

In my NextJS app, I have a /home page in which I need x and y overflow to be hidden. However, I have another /books page in which I need the user to be able to scroll. However, as there is only one global stylesheet in Next and global css selectors like body are not allowed in css modules, I could not find a way to get around this. Any ideas?

Done! Just insert the following into the component:
<style global jsx>{`
html,
body {
overflow: hidden;
}
`}</style>

You already gave the general right answer how to add global stylesheets from specific page or component. However, for this specific case of hiding scrollbar in React application, I can suggest to take a look at useLockBodyScroll from package react-use.
https://github.com/streamich/react-use/blob/master/docs/useLockBodyScroll.md

Related

Why does React randomly chose a different Stylesheet instead the one I imported?

I have a React App with the following folder structure.
All my "pages" have their own Folder with a .jsx file and a .css to style the page.
I imported the CSS in the HomePage.jsx like:
import '../HomePage/HomePageStyles.css'; //HomePage.jsx
So far, everything is working just fine. Then I created the ChampionDetailPage.css and imported it in the ChampionDetailpage.jsx like that.
import '../ChampionDetailPage/ChampionDetailPageStyles.css'; //ChampionDetailPage.jsx
Now things start to get funny. The HomePages.jsx suddenly start to use styles from ChampionDetailpage.css that have the same class names without any obvious reason.
The goes vice versa, so the ChampionDetailPage.jsx uses classes from the HomePageStyles.css as well.
For example, I have the class .content-right in both .css files
.content-right{ /* HomePage.css */
width: 55%;
}
.content-right{ /* ChampionDetailStyles.css */
display: flex;
padding-right: 20px;
flex-grow: 100;
flex-direction: column;
}
In this case, React somehow styles my Homepage.jsx with the ChampionDetailPages.css which is also visible in the Chrome dev tools.
Why does that happen and how do I fix it?
Things I tried already:
Changing the import eg. import './ChampionDetailPageStyles.css';
Throwing the CSS into its own directory
in both cases, the problem remains the same!
Thanks for your help in advance.
You can't have stylesheets with classes that overlap eachothers.
Then, the class that is taken in consideration is the one that was in the css that was loaded the last. This is why you have each of the two classes that are picked up randomly.
What you must know When you import a css this way:
Its content is not scoped for your file that imports this css.
It will be imported globally, and then, classes that are defined inside will be shared to every dom content of your aplication during its whole lifecycle.
You have no control on the order of importation of your css over the time.
To summarize, the stylesheet is not actually picked up randomly, it is the one that happens to be loaded the last that overrides every class that was already defined in the previously loaded css.
Something to know, all the css that you import in your client application are ALL loaded at the bootstrap.
A better way to manage styles with React is to use Emotion. A framework that permits to handle css with your program, and also to be able to scope your styles to your component, or to share it with several components.

How to print only one specific vue component?

I'm making diploma which needs to be downloadable.
So I made specific vue component (diploma itself) which is in the dom but hidden with v-show (display: none).
Now I only need that specific component to be printed (or saved as pdf) and not a whole page.
So I cannot initiate window.print(), but I need somehow to sandbox specific component, so I figured I could use hidden iframe and load component there and initiate print on iframe.contentWindow.print().
One problem is I don't see how I can load component in an iframe.
One way would be to use something like
iframe.srcdoc = downloadRef.value.$el.innerHTML;
but I don't have styling this way.
I also tried something along the lines of
iframe.srcdoc = ` ${css} ${downloadRef.value.$el.innerHTML}`;
where css is style tag string with styles, but again not all styles are applicable.
Is there any other way to load vue component into iframe and to render it as such (with vue naturally), or is there any other way to make certain component printable with all necessary styles applied, without using iframe at all?
Thanks in advance.
I think there's an easier way to achieve what you need without using iframe.
What if you could apply a certain css styling for that component, which would make it occupy the whole page and cover all other content
<style>
.overlay {
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
z-index:1000;
}
</style>
Credit goes to How to make a div fullscreen and atop of all other elements with jQuery?
You would then be able to add a conditional class on your special component:
<special-component :class="{'overlay': isPrintModeEnabled}"> ...
So all that's left is to enable the isPrintModeEnabled property as per your rquirements.

Blanket stop CSS from cascading to a certain element not using iframe

I have an entire page that will be PHP included onto an already established website. The website will include my site after the <body> tag on their own site. I do not have access to the <head> section of the page. I am including my <link> and <script> tags in my page (so after the <body> of the parent page). I can change the title dynamically with javascript after the fact.
However, the CSS from the parent page is causing some interference with some of my elements that aren't explicitly styled. I would like a blanket way to stop CSS from cascading to my own elements without using an iframe. Is there a CSS reset that will work? How about a javascript solution? Would HTML5 scoped styles fix this issue eventually?
I can't give you a good answer. The closest I can think of is to take one of the CSS Reset scripts and apply them to your root <div>.
It's still a long list of things you're cancelling but at least it's maintained by someone else...
You can try by wrapping content and appending CSS rules only to wrapped content, for example.
CSS
#wrapper1 .className{/* RULES */}
#wrapper1 div{/* RULES */}
#wrapper2 .className{/* OTHER RULES */}
#wrapper2 div{/* OTHER RULES */}
HTML
<div id="wrapper1">content 1</div>
<div id="wrapper2">content 2</div><!-- CONTENT YOU APPEND LATER -->
Another solution, not the best1 is maybe to use jQuery and replace all class-es or ID-s in body when content is changed, here again you should define CSS before.
There is one thing I must note, in my experience appending HTML as pure text (like innerHtml='html') get right CSS rules in Google Chrome and Mozilla, but on IE you need to use proper JS and append content differently to get those CSS rules used. By different I mean like creating element should really be creating new element with JS function.. that was before I am not sure anymore if this thing is changed.

Disabling Bootstrap CSS inside a certain container, stop overriding css

I am currently using bootstrap and knockoutjs to display a webpage that has a live preview of some data. For instance, a user enters a title, in a textbox, on the left hand side. Then, the right hand side of the page updates to format that text based on some other settings. So it might be something like <h1>{title}</h1> or it might be <u>{title}</u>. However, all that is requested from the user, at this point, is the title in plain text.
The issue is, as the preview is actually a HTML document created by the users. So, some of the bootstrap CSS overrides the CSS specified by the users. So the above <h1> will inherit bootstraps h1 CSS class, rather than using whatever is in the users HTML template. This means at the time of using the created document, the preview may differ to what is actually happening.
JSFiddle example: http://jsfiddle.net/Piercy/4fcmk/
HTML:
<div class="content">
<h1>Header 1</h1>
<div id="Preview">
<!-- Start Html Template -->
<style>
.header
{
color: red;
}
</style>
<h1 class="header">Header Class</h1>
<!-- End Html Template -->
</div>
</div>
CSS:
.content h1
{
color: blue;
}
The user would expect "Header Class" to be red as they do not know anything about the content css. In my code i am using bootstrap but this shows a simplified version of the issue. Normally, you would just make the CSS more specific but because the user doesn't know about bootstrap (or in the jsFiddle example content) we can't really expect them to modify the CSS.
I need to try figure a way to either stop a certain container (preview div in the jsFiddle) using the stylesheet thats being used by it's parent or figure a way i can modify the bootstrap CSS so that overriding issues are less likely.
Of course, sticking it in an iframe would accomplish this but then I will have issues trying to access and modify the preview.
I am open to all ideas, just want to try find the most appropriate way to deal with this situation. I found this rather difficult to put down on paper so I apologise if it is hard to understand.
To my understanding, there is no way to tell CSS to not inherit styles. However, here's an interesting idea for a workaround.
Take the bootstrap.css file and drop it into your CSS preprocessor of choice (I used LESS).
Next, wrap ALL of the styles with an ID or class of bootstrap like this:
#bootstrap { ...all the bootstrap styles go here. }
Then, save it as a .less file and compile it. Your result will be all the bootstrap styles inheriting from #bootstrap or .bootstrap (depending whether you used an ID or class to wrap bootstrap's styles).
Finally, wrap whatever markup in your template that your users will not be editing in a div and give this div an id of #bootstrap or class of .bootstrap, and include only the bootstrap file we just processed using LESS.
That takes care of the user's CSS not inheriting from bootstrap. However, your users can still write styles that bootstrap will inherit. To get around this, wrap the user's content in an id or class of something like #user or .user and ask them to begin all of their styles with .user > likes this:
.user > h1 {color: red;}
.user > p {font-size: 18px;}
This should separate your HTML template's styles from your users' styles - it just takes a little bit more work from your users.
Here's a jsfiddle to demonstrate:

Toggle visibility of content in web app

This question is not about how to toggle a div. But instead how to toggle visibility in a big web app. My web app needs only to run on Chromium (Webkit). The problem I have is probably more related to infrastructure and best practices, and I wonder if anyone has experience with this.
My app runs on node-webkit, which means all files are local, and loading is quick. To feel really snappy, I add all content to the DOM I possibly can. I want to stay away from state changing my app with Javascript, so no $('.view-projects').addClass('visible');. Because it will get messy really soon, and I feel it's not really the task of JS.
Instead the approach I have chosen works like this.
// javascript sample (I actually code in CoffeeScript)
// catch all click events on elements with data-trigger attributes
app.on('view:addProject', function () {
// add a class to the root view
$('#app').addClass('view-addProject');
}):
Markup:
<!-- markup sample -->
<div id="app">
<div class="projects">
<div data-trigger="view:addProject"></div>
<div>etc.</div>
</div>
<div class="addProject">
etc.
</div>
</div>
Css, used as the state machine:
app.view-addProject .addProject {
visibility: visible;
display: block;
}
What I want to know is if other people have tried something like this, have good experiences with other approaches etc. Or maybe I am missing something, I feel I am getting myself in trouble with dynamic content.
Note: I can't simply use show/hide, since my elements use display: -webkit-flex/-webkit-box; etc.
If you want to toggle visibility, here are some alternative approaches:
Control state by changing CSS via the CSSOM
Change state by changing data- attributes
Change state by changing DOM nodeNames

Categories

Resources