I'm trying to make a react component that changes the width from a parameter but it's doesn't work and I don't know why.
function Bar() {
const p =80
const style = `bg-slate-500 h-8 w-[${p.toFixed(1)}%]`
console.log(style)
return (
<div className=' h-8 w-full'>
<div className={`bg-slate-500 h-8 w-[${p}%]`}>
</div>
</div>
)
}
export default Bar
With this code I get a full-size bar, but if I use a strict String with 80.0 it works fine
The other answers are wrong. In Tailwind V3 JIT is included and you won't need to set mode to jit anymore. And even in Tailwind V2 the posted code wouldn't work.
Following the docs, you must avoid string interpolation and use complete class names.
This is wrong:
<div class="text-{{ error ? 'red' : 'green' }}-600"></div>
Instead use Complete class names:
<div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>
What about using inline styles?
You may be tempted to use inline styles, but remember Content Security Policies are increasingly under scrutiny to disallow unsafe inlines. Any inline style or script could in theory be injected with unintended content. Furthermore, the whole point to Tailwind is to generate CSS at build time, so you'd be working around it and might as well not even be using it in this case.
in tailwind.config.js add mode: 'jit'.
I would suggest https://v2.tailwindcss.com/docs/just-in-time-mode to learn more.
e.g:
module.exports = {
//other options
mode: 'jit',
}
I ran into a similar issue building a site with Astro & Tailwind.
The solution I discovered was to use the 'safelist' feature that allows you to define certain classes that will be force-compiled, regardless of whether or not they are found when scanning the specified content locations in the tailwind.config.cjs file.
An example of the code I used to fix my situation:
module.exports = {
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
Adding a safelist and classes to it:
safelist: ["lg:grid-cols-[1fr_4fr]", "lg:grid-cols-[1fr_3fr_1fr]"],
...
Here's a link to the relevant area in the Tailwind documentation.
If your p's value is a constant that will be used across the app, you can instead define it in your tailwind.config.js file like this.
theme: {
extend: {
spacing: {
"p-value": "80%",
},
},
}
Then you can modify your code to this.
<div className="bg-slate-500 h-8 w-p-value">
Include mode: 'jit' in tailwind config file
Related
I am developing an app using NuxtJs 3. In nuxt 3, layout feature has been changed. We can use layout via <NuxtLayout name="layoutName"> and this layoutName is in layouts folder. My problem is,layout is in another folder inside layouts directory. How can i use that?
Not sure to fully understand what you want to have at the end, but let's say that you want to change the path of the layouts directory with the dir property.
You can do that with the following in nuxt.config.ts
import { defineNuxtConfig } from 'nuxt'
export default defineNuxtConfig({
dir: {
layouts: 'fancyLayouts/nested'
}
})
Then, all of your layouts will be available in that directory
Now, we have a very simple other.vue layout with the following (custom.vue is almost the same)
<template>
<div>
<slot />
<br/>
<p>other layout</p>
</div>
</template>
We could have the following in /pages/index.vue
<script>
definePageMeta({
layout: false,
});
export default {
data: () => ({
layout: "custom",
}),
};
</script>
<template>
<NuxtLayout :name="layout">
<button class="border p-1 rounded" #click="layout === 'other' ? layout = 'custom' : layout = 'other'">
Switch layout
</button>
</NuxtLayout>
</template>
This will allow us simply switch from one layout to another successfully aka custom or other.
If what you want is to have 2 directories like:
/layouts/custom.vue
/layouts/nested/other.vue (nested 1 level more)
Then, I did not achieved to have a simple way of managing the import regarding a layout.
I've never seen this kind of configuration and I'd even say that if you have a lot of various layouts (to the point of nesting them), then I recommend wrapping your content inside of components rather than layouts anyway.
Because layouts are meant to be quite simple global outside wrappers for the pages, nothing regarding a complex structure. It's more of a component's purpose.
This feature was added in Nuxt 2 long ago.
Adds support for folders in /layouts #1865
Nuxt.js does not respect layouts in separate folders. #1854
It does not seem to work the same way in nuxt 3 because I'm facing the same issue.
Layouts inside folders Nuxt js 3
update...
I checked the source code for Nuxt 3 and definitely is not supported what you are trying to do.
example: layouts/folder/custom.vue
and then use it in pages like follows
<NuxtLayout name="folder/custom">some code ...</NuxtLayout>
I just sent a PR for this feature.
Adds support for folders in /layouts #5796
Hopefully it gets accepted or at least it gives someone the idea to add this.
I have a React project that uses CSS Modules by importing .css files. e.g. import styles from "./styles/MyComponent.css";
I find myself now in a situation where a component is receiving a customized snippet of CSS as a string in response to a dynamic call to the server.
Is it possible to take this string (which is unknown until runtime) and essentially do the same thing to it that import does to the .css file when it is compiled by webpack?
For example:
import styles from "./styles/MyComponent.css";
//later on in component...
moreStyle = "a string containing valid CSS";
//do *something* here to moreStyle string to do whatever importing does to a file.
myJSX = (
<div className={styles.someClass}>
This div content is styled by someClass
</div>
<div className={moreStyle.someOtherClass}>
This div content needs to be styled by someOtherClass, but obviously this isn't working
</div>
);
You can try this:
import styles from "./styles/MyComponent.js";
myJSX = (
<div style={styles.someClass}>
This div content is styled by someClass
</div>
<div style={styles.someOtherClass}>
This div content needs to be styled by someOtherClass, but obviously this isn't working
</div>
);
Consider creating a serialized object, instead.
// Filename: MyComponentStyle.js
//Example styles
export const styles = {
someClass: { height: 10 },
someOtherClass: {
backgroundColor: 'red',
}
};
React doesn't work like your typical HTML/CSS/JS app. The thing to note that JSX may look like HTML but it is not HTML.
In your code, className is being defined as a string, which is expected, however, there's possibly no CSS being referred to in this document. Try to console.log it and see what you get.
...
Another possible solution is to simply have your style within the same component file. A common design choice for component styling is inline styling. This is especially useful for projects of medium-large scale, where managing files can get difficult.
Helpful references:
https://reactjs.org/docs/dom-elements.html#style
https://codeburst.io/4-four-ways-to-style-react-components-ac6f323da822
I would like to hide a div when print preview happens but I find it almost impossible to do it in a React.
<div className="contacts"></div>
Is there any possibilities that I can add pure css or if React Stylesheet supports #media print and hide element with class name contacts when print preview.
I was reading this article https://blog.logrocket.com/the-best-react-inline-style-libraries-comparing-radium-aphrodite-emotion-849ef148c473 but it just seems too much work for something that I would do poorly in css within a matter of seconds.
Any idea how can I achieve such thing in Reactjs?
Inline media queries are not possible. The closest you can get is inlining a stylesheet, like so (in React syntax):
<div className="contacts">
<style>
{`#media print {.contacts{display: none;}}`}
</style>
</div>
A bit old but maybe it will be useful for someone. If you want to use React styles you can also do:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
contacts:{
display: "block",
},
[`#media print`]: {
contacts:{
display: "none",
},
}
}))
...
const classes = useStyles();
...
<div className={classes.contacts}></div>
This markup works for me with FunctionComponents flawlesly.
You cannot use media queries (also pseudo-classes and pseudo-selectors) inside inline styles. You need to extract your css into a sepparate .css file and to import it either inside your component's file (if you use bundlers like webpack) or just include it inside your html with <link> tag
I am trying to learn react. I see a lot of style change inside java script so far. As far as I know, the style should onle be managed by css files. But I am not sure this rule also applies to React. What is the best practice for react. For instance, is the following code a clean code, or is changing the style in the React component a smell and need to be refactored? If so, how it could be refactored?
“const Color = ({ title, color}) =>
<section className="color">
<h1>{title}</h1>
<div className="color"
style={{ backgroundColor: color }}>
</div>
</section>”
I prefer to connect external .css file - it's much more clean.
If there is a need to keep styles in .js I would organize the code in that way:
const styles = {
color: 'red',
fontSize: '2rem',
backgroundColor: 'forestgreen'
}
And I would apply the styles I need just like here:
<div style={{color: styles.color, fontSize: styles.fontSize}}></div>
Or, If I need to apply all styles:
<div style={styles}></div>
That is totally depends on our requirement and preferences. Inline styles are concerned with only component they are written into. You can structure css based on your components so it becomes reusable. You can declare your css in to your components in variables as well as in separate asssets directory.
Well it is more about code readability and re-usability. Webpack writes your all css/scss in a single file and inject into your index.html. You should look into JSS so you can compile your css and later inject it into your component as props. Anyways there are a lot of resources that you can leverage from.
You can also use styled components https://www.styled-components.com/
I have a simple react HTML input component and as it used on different sections/pages, I added some props for styling it and its placeholder. The problem is that sometimes I got an error on the compilation(we are using nextjs).
This the code:
{placeHolderColor && (<style jsx>{`input::placeholder{color:${placeHolderColor}}`}</style>)}
Basically, I'm using an inline If with Logical && Operator inside the render function to check if the prop placeHolderColor exists, and if exist add the style tag.
The error I'm getting:
Warning: Unknown prop jsx on tag. Remove this prop from the element.
The error only occurs when you reload the page. If you made a change and the hot code reloading run, there is no error. Not sure if the problem is the var inside the literal, the '::placeholder' pseudo-element or what. The code works anyway, and if the placeHolderColor var is defined the style is applied.
When I tested your code I got the same error(also on page load). After that I talked to a styled jsx dev with nickname #g (on github #giuseppeg) on ZEIT's #next slack channel https://zeit.chat/ and he confirmed that the conditional use of <style jsx> tag is not supported. Here is his explanation https://github.com/zeit/styled-jsx/issues/233.
Also, after removing conditional and just inserting your tag like this:
<style jsx>{'input::placeholder{color:${placeHolderColor}}'}</style>
I've got this error:
Module build failed: SyntaxError: Expected placeHolderColor to not come from the closest scope.
Styled JSX encourages the use of constants instead of props or dynamic values which are better set via inline styles or className toggling. See https://github.com/zeit/styled-jsx#dynamic-styles.
According to recommendations from https://github.com/zeit/styled-jsx#dynamic-styles, you basically should not add dynamic values into template literals inside <style jsx> tag (though you can put there constants and constant expressions starting from version 1.0.4 (see UPDATE at the bottom of the answer for details)). The reason behind the prohibition of using props/dynamic values, according to #giuseppeg comment in the slack thread https://zeit-community.slack.com/archives/C2U01UYEA/p1496928897076534, is following: "at the moment styled-jsx compiles and produces static code and therefore the hashes that make the final CSS unique won't change when the value of a variable like color changes"
So, as you see from documentation, it is recommended to use dynamic values via inline styles or className toggling. Unfortunately, styling pseudo-elements (placeholder etc.) in not possible via inline styles in React, so if you have finite number of possible colours then create a class for each colour case and use it like this:
const InputWithColouredPlaceholder = props => (
<div>
<input
placeholder="text"
className={
'placeholderColourClass' in props && props.placeholderColourClass
}
/>
<style jsx>{`
.reddy::placeholder {
color: red;
}
.greeny::placeholder {
color: green;
}
`}</style>
</div>
);
and render it like <InputWithColouredPlaceholder placeholderColourClass="reddy" />
It gets more complicated in case of large range of possible colours though. In this case I would recommend to ask for suggestions in #next channel on ZEIT's slack https://zeit.chat/.
UPDATE
Using constants and constant expressions in template literals should work in styled-jsx 1.0.4 (but nextjs currently depends on 1.0.3, and separate installation of styled-jsx will not help, so wait for update of nextjs to support styled jsx 1.0.4). It means that any constants that are not passed trough props and not created inside component should work (for example you can have a js file with constants for colours and import them into your input component). But it does not fit your case because you need a dynamic way.
I got error Warning: Unknown prop 'jsx' on <style> tag. Remove this prop from the element. For details, see FB react-unknown-prop. What does that jsx property in your style tag means? Just remove it?