How do you style a single element component, if the element does not accept children?
For example, this will not work:
export default ({url, alt}) => (
<img src={url} alt={alt}>
<style jsx>{`
img {
max-width: 100%;
max-height: 40vh;
}
`}</style>
</img>
)
Is there a way to avoid adding a superfluous container div?
@jaydenseric I thought your example worked, doesn't it?
Tags such as img, input etc. that can't have children error.
Oh right, I just tried on the babel repl which obviously doesn't complain.
For now I am afraid that you'd have to use a container but this is definitely something that we need to figure out and fix also because in the future with React Fiber we will need to support siblings.
Yeah this would be nice. We can pass a string to the style attr, but it wouldn't cover states and such.
Hi guys,
I just stumbled across this issue as I'm thinking of switching from styled-components.
Has this been solved by being able to target the root element?
Thanks
@gilesbutler nop. You still need a container for the image unfortunately. This will be fixed once we add support for React 16 fragments / return arrays.
@gilesbutler No that wouldn't help.
The issue is <style jsx>...</style> needs to squeeze in-between elements that have closing tags. Like <img /> doesn't have <img></img> so we can't have a stateless component like:
// derp.js
export default () => <img src="pic.jpg" <style jsx>{` height: 50px; `}</style> />
tbh, I don't see how this is an issue now that I'm older.
You can write something like this I assume:
// yay.js
export default () => <img src="pic.jpg" style={{ height: 50 }} />
And with styled-jsx v2+, I assume you can even pass props/state into it:
// 🤤.js
export default propStyles => <img src="pic.jpg" style={ propStyles } />
@giuseppeg Do you see a use case I'm not seeing? Seems like it's not even an issue.
@corysimmons using vanilla React inline styles skips vendor prefixing, minification, etc. Also keyframes and media queries are not possible inline.
@jaydenseric Ah! All good points. Thank you! =)
This is a temporary workaround I guess
export default ({url, alt}) => (
<span>
<img src={url} alt={alt} />
<style jsx>{`
span, img { max-width: 100%; }
img { max-height: 40vh; }
`}</style>
</span>
)
But @giuseppeg that will leave a margin under the img so be sure to add <span style={fontSize: 0}> if you're wrapping an image. 👍
@corysimmons img { vertical-align: middle } should fix that
Well played.
Ah ok awesome, thanks for the updates guys 👍
Giles Butler
giles.io | linkedin.com/in/gilesbutler
On 11 Dec 2017, 7:14 PM +0800, Cory Simmons notifications@github.com, wrote:
Well played.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
With the introduction of Fragments it's now possible to do this.
function Input(props) {
return (
<Fragment>
<input {...props} />
<style jsx>{`
input {
border-bottom: 1px solid red;
}
`}</style>
</Fragment>
)
}
@sergiodxa would something like this be enough https://github.com/zeit/styled-jsx/issues/383#issuecomment-358287330 ? In cases like this you could just do:
const scoped = css.resolve`
input { border-bottom: 1px solid red; }
`
function Input(props) {
return (
<Fragment>
<input {...props} className={`${props.className || ''} ${scoped.className}`} />
{scoped.styles}
</Fragment>
)
}
@giuseppeg what I mean to say is: with Fragments this issue is not a problem anymore.
oh right, sorry I though I read "not" :) 👍
Yes, I used <Fragment></Fragment> in the end. Soon this will be even easier with <></> syntax.
Most helpful comment
With the introduction of Fragments it's now possible to do this.