I'm creating a component and I want to pass a style attribute via props to an internal div, but I get this error when trying to assign float:left
Unknown prop float on tag. Remove this prop from the element.
My component:
<Badge style={{width:'10em',float:'left'}}
color={props.user.color}
initials={props.user.initials}
name={props.user.name} />
the component code:
render() {
const {color,initials, name, style} = this.props;
return (
<div {...style}>
<div className="badge-wrapper">
<div style={{'backgroundColor': color}} className="badge">
{
initials.toUpperCase()
}
</div>
</div>
{name}
</div>
);
}
I don't see the issue with setting up a float left on a simple div, any recommendations?
Change
<div {...style}>
to
<div style={style}>
You are using JSX Spread attributes to apply your css properties to the div as attributes when all you really wanted to do was assign them to the style prop.
Related
I am trying to set the background image under my components. But it always is on top, so my elements are under it.
Or in the second variant, all works fine, except that I can't apply blur-xl only to the background. it applies to background and Layout elements.
bg-repeat-y needs me to copy down my image, am I right?
import moons from './../assets/moon.svg'
const Background = ({ children }) => {
return (
<div className='bg-white '>
<div className='min-h-screen min-w-screen bg-repeat-y' style={{ backgroundImage: `url(${moons})` }}>
<div className="div"></div>
</div>
{children}
</div>
);
}
export default Background;
This Background element wraps other elements in Laoyout in react-router-dom
export const AppLayout = () => (
<div>
<Background>
<NewNavbar />
<Outlet />
<Footer />
</Background>
</div>
);
Help me, please!
try this, the blur will be applied between your components & background image
export const AppLayout = () => (
<Background>
<div class="backdrop-blur-xl h-full">
<NewNavbar />
<Outlet />
<footer />
</div>
</Background>
);
if you have any queries, refer to this link
https://play.tailwindcss.com/yX9aAMagRj
For the first variant/approach that you mentioned, you can set the z-index of the background to negative using the class -z-10 . Then your background will not come over your other elements.
How to make the selected div element to be 100% in the inspect element tool in the picture below. I am using display:flex on .dvPageNotFound class and I want to apply height:100% on the div element inside it. If we put display:flex on parent element then all the child elements gets stretched by default, but here I don't get my child element stretched. I don't know why? I am using 12 column grid system same as bootstrap 4 grid Any help would be appreciated.
HERE IS THE CODE -
import React from 'react';
import { Link } from 'react-router-dom';
const PageNotFound = () => {
return (
<>
<div className="dvPageNotFound d-flex">
<div class='col-12'>
<h1 className="heading-lg">Page Not Found</h1>
<p className="my-3">The page you are looking for we coudn't found.</p>
<Link to="/" className="btn btn-black">
Back to Homepage
</Link>
</div>
</div>
</>
);
};
export default PageNotFound;
This worked for me. I added height: 100vh and added m-auto classes which we get from the 12 column grid.
import React from 'react';
import { Link } from 'react-router-dom';
const PageNotFound = () => {
return (
<>
<div className="dvPageNotFound d-flex justify-content-center align-items-center" style={{ height: '100vh' }}>
<div className="m-auto">
<h1 className="heading-lg">Page Not Found</h1>
<p className="my-3">The page you are looking for we coudn't found.</p>
<Link to="/" className="btn btn-black">
Back to Homepage
</Link>
</div>
</div>
</>
);
};
export default PageNotFound;
I'd like to align some text with a logo on the same line:
<div id="container" style="white-space:nowrap">
<div id="image" style="display:inline;">
<Link href="" target="_blank">
<img
src={img}
loading="lazy"
width="40px"
height="40px"
alt=""
/>
</Link>
</div>
<div id="texts" style="display:inline; white-space:nowrap;">
<strong> 75 </strong>
</div>
</div>
But when I try to run it, I receive these errors:
Line 61:41: Style prop value must be an object react/style-prop-object
Line 62:41: Style prop value must be an object react/style-prop-object
Line 73:41: Style prop value must be an object
In react you need to use in style in object,
https://reactjs.org/docs/dom-elements.html#style
style={{
whiteSpace:'nowrap',
display:'inline',
}}
style prop takes an object.
Full code:
<div id="container" style={{ whiteSpace: "nowrap" }}>
<div id="image" style={{ display: "inline" }}>
<Link href="" target="_blank">
<img src={img} loading="lazy" style={{ width: "40px", height: "40px" }} alt="" />
</Link>
</div>
<div id="texts" style={{ display: "inline", whiteSpace: "nowrap" }}>
<strong> 75 </strong>
</div>
</div>
CodeSandbox Demo
Before we can answer the question you ask in the title of this post, you have to fix your inline styles, hence the error you receive from React. The answer to your question using CSS will be at the bottom of the post.
When using inline styles in React, you will need to create an object. An object is the use of key, value pairs. So, using the code given in your example, style="display:inline;" is not an object, and thus will not work as you have seen. To make this inline style work, you will need to do one of the following.
Create an object within the JSX
This method can get messy, so if you are planning to write all your styles as inline styles, I suggest using method 2.
To do this, you can follow #RiTeSh 's example. You will need to create an object and pass that to the element's style prop, WHICH CANNOT BE A STRING, as you can see from the errors you are getting. You can do the following:
// Notice how the value is the only string in the object.
style={{
whiteSpace:'nowrap',
display:'inline',
}}
And to see what this would look like when used in an element:
<div style={{whiteSpace:'nowrap', display:'inline'}} >
Hello World
</div>
Store the styles in a variable
Compared to method 1, this is a much cleaner way to add inline styles as it doesn't create a jumbled mess in your render() function.
Before you reach the render() function, create an object and store it in a variable like the one below.
const styleObject = {
whiteSpace:'nowrap',
display:'inline',
};
return (
// Your JSX here
);
And when you apply the styleObject to the JSX element, it should look like the following:
return(
<div style={styleObject} >
Hello World
</div>
);
Make img and text appear on the same line
This is quite a simple answer if you use the display: flex property on the wrapper element, which, in your case, is the div with an id of container. Here is a simple read about flexbox from W3 Schools
With inline styles on the container element:
style={{display: 'flex'}}
With CSS:
#container {
display: flex;
}
Both CSS (one in light dom and one in shadown dom) effect on tag.
Name and Phone are effected by global CSS at and Shadow Scope CSS too!!!
WHY ????? I dont want it.
I expected they are just effeted by Sahdow scope CSS which is in template scope.
I wish I have some ideas from you.
https://plnkr.co/edit/Asr1S1UFvhmhtZeWm5k8
//CREATE CUSTOM ELEMENT
var MyContactProtype = Object.create(HTMLElement.prototype);
MyContactProtype.createdCallback = function() {
//retrieve template
var tpl = document.querySelector('#contact-form-tpl');
var tpl_ct = document.importNode(tpl.content, true);
//this <=> my-contact element -> create shadow
var shadowRoot = this.createShadowRoot();
//show template in shadow DOM
shadowRoot.appendChild(tpl_ct);
};
//REGISTER CUSTOM ELEMENT
document.registerElement("my-contact", {
prototype: MyContactProtype
});
span {/* global CSS*/
text-decoration: line-through
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/document-register-element/1.11.0/document-register-element.js"></script>
<span>HELLO</span>
<!--line through by css at LINE 6: OK-->
<my-contact>
<h1 class="header-contact-form">Contact X</h1>
<span class="name">this is my name</span>
<span class="phone">this is my phone</span>
</my-contact>
<template id="contact-form-tpl">
<style>
span {/* shadow scope CSS*/
text-decoration: underline
}
</style>
<fieldset>
<legend>
<content select="h1.header-contact-form"></content>
<!--
Name and Phone are effected by CSS at line 6 and 21 too!!!
WHY ????? I dont want it.
I expected they are just effeted by CSS line 21 which is in template scope.
-->
<div>
Name: <span><content select="span.name"></content></span>
</div>
<div>
Phone: <content select="span.phone"><span></span></content>
</div>
<span>TEST</span><!-- only apply css at line 21: OK-->
</legend>
</fieldset>
</template>
It's the normal behavior of CSS styles. The elements inserted in the Shadow DOM with <content> (in your example: <span class=name>...</span>) are actually part of the normal DOM, and therefore are affected by the global CSS styles.
If you don't dont want it, you should try another technique, like copying the light DOM elements into the Shadow DOM instead of using <content>.
Also, you should use Custom Elements v1 (and customElements.define()) and Shadow DOM v1 (and <slot>) instead of Custom Elements v0 (registerElement()) and Shadow DOM v0 (<content>) which are deprecated.
With Shadow DOM v1, you can use ::slotted() inside the Shadow DOM to select and style insterted elements.
You can then overload the CSS rule in the Shadow DOM <style> with the !important modifier:
line 21:
<style>
::slotted( span ) {
text-decoration: underline!important
}
</style>
Below is the complete snippet:
//CREATE CUSTOM ELEMENT
class MyContact extends HTMLElement {
constructor() {
super()
//retrieve template
var tpl = document.querySelector('#contact-form-tpl');
var tpl_ct = document.importNode(tpl.content, true);
//this <=> my-contact element -> create shadow
var shadowRoot = this.attachShadow( {mode:'open'}) //createShadowRoot();
//show template in shadow DOM
shadowRoot.appendChild(tpl_ct);
}
}
//REGISTER CUSTOM ELEMENT
customElements.define("my-contact", MyContact);
span {
text-decoration: line-through
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/document-register-element/1.11.0/document-register-element.js"></script>
<span>HELLO</span>
<!--line through by css at LINE 6: OK-->
<my-contact>
<h1 slot=header>Contact X</h1>
<span slot=name>this is my name</span>
<span slot=phone>this is my phone</span>
</my-contact>
<template id="contact-form-tpl">
<style>
span ::slotted( span ),
span {
text-decoration:underline!important
}
</style>
<fieldset>
<legend>
<slot name=header></slot>
<div>
Name: <span><slot name="name"></slot></span>
</div>
<div>
Phone: <slot name="phone"><span></span></slot>
</div>
<span>TEST</span><!-- only apply css at line 21: OK-->
</legend>
</fieldset>
</template>
I am having trouble getting my styled component to make a change to an <input /> wrapped in a React component. In Dev Tools I can see the style I am trying to override here:
.ui.input input {...}
I think the wrapping component needs to pass className to input i.e
<input className = {this.props.className} ..> ... </input>
but I cannot get the style to override with or without that. I will provide some snippets below.
//styled component
const StyledSearch = styled(Searchbar)`
&.ui.input input{
border: 0px !important;
}
`;
class SearchBar extends Component {
...
render() {
const style = {
display: this.state.showResults ? 'block' : 'none',
maxHeight: 500,
overflowY: 'scroll',
};
return (
<div className="ui search fluid" ref="container">
<div
className={`ui icon fluid input ${this.props.loading ? 'loading' : ''}`}>
<input type="text"
placeholder={this.props.placeholder}
onFocus={this.focus}
className = {this.props.className}
value={this.props.value}
onChange={this.props.onChange}/>
<i className="search icon"></i>
</div>
<div
className="results"
style={style}>
{
this.props.results.map((result, index) => (
<a
className="result"
key={index}
onClick={this.select.bind(this, result)}>
<div className="content">
{
result.get('image') ?
(
<div className="image">
<img src={result.get('image')} style={{ maxWidth: 50 }}/>
</div>
) : null
}
<div className="title">
{result.get('title')}
</div>
<div className="description">
{result.get('description')}
</div>
</div>
</a>
)
)
}
</div>
</div>
);}}
Basically, styled-components creates a new unique class name (in other words, a new namespace) for any DOM or React Components for which the styled function is called.
That means, when you use styled(SearchBar), styled-components wraps SearchBar component and attaches a unique class name to its root DOM. Then it passes that unique class name to the descendent DOMs and components (in your cases, nested div, input, a).
For this method to work, your root DOM must have a className that can be configured from outside. That's why, styled-components expects that, root DOM has the definition ${this.props.className} as the value of its className props. If your component lacks this, styled-components will not be able to create a new namespace which it can use to apply styling specific to it.
So, for your technique to work, you must assign ${this.props.className} as one of the values of className prop defined at the root div of SearchBar.
Working Demo
If you don't have access to SearchBar, you can wrap it with another component. Overhead of this process is that, you have to use an extra DOM level
Working Demo
From what I can tell, you need to apply the styles generated with styled-components to the wrapper element. This is due to the specificity of the .ui.input input external style. Meaning we can't simply target the input element with a new style because the .ui.input input selector is more specific and takes precedence. Here's a simple CSS example showing how the specificity of the .ui.input input selector takes precedence over the input styling:
.ui.input input {
border:2px solid red !important;
}
input {
border: 0px !important;
}
<div class="ui input">
<input />
</div>
This same issue is at play in your case. In the example below I've created a new Wrapper component, which has a style of:
&.ui.input input {
border: 0px !important;
font-size: 24px;
}
defined on it. This targets the inner input element, with more specificity, to override the external styles.
import React from 'react';
import ReactDOM from 'react-dom';
import styled from 'styled-components';
class InputWrapper extends React.Component {
render() {
const Wrapper = styled.div`
&.ui.input input {
border: 0px !important;
font-size: 24px;
}
`;
return(
<Wrapper className="ui input">
<input type="text" placeholder="Input" />
</Wrapper>
)
}
}
ReactDOM.render(
<InputWrapper />,
document.getElementById("app")
);
Here's a WebpackBin example.
Currently at version 4 you can do it as simple as
const Input = styled.input`
border:2px solid red !important;
`;
it will rendered as native input with SC className