样式化组件,两层 className - 如何在组件声明中应用样式?
[英] Styled components, two layers of className - How would I apply style in component declaration?
本文介绍了样式化组件,两层 className - 如何在组件声明中应用样式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我在 next.js 中创建了一个具有组件样式的 Container 组件.当我声明在整个站点中使用此容器组件时,我想为其添加一个 className 并根据其使用上下文对其进行主观设置.
这是我的容器组件的示例:
const Container = (props) =>(<><div className="容器">{props.children}
<样式jsx>{`.容器{宽度:100%;最大宽度:1200px;边距:0 自动;}`}</style></>)导出默认容器;
所以,我想给它最大宽度为 1200 像素,并用自动边距居中.没问题,我已经这样做了.
现在,我打算在我网站的标题中使用这个组件.但是在标题的情况下,我希望 Container 组件是一个 flexbox:
从'./Container'导入容器const Header = (props) =>(<><标题><Container className="header-col"><div><h1>{props.title}</h1>
<导航><ul>{/* 导航项 */}</nav></容器></标题><样式jsx>{`.header-col{显示:弹性;对齐内容:间隔;}`}</style></>)导出默认标题;
当我查看该站点时,我注意到我在标题中为 Container 组件指定的 flexbox 样式不存在.
我期待 className 生效,并允许我添加其他样式.
我相信这与它认为 className 不是类名,而是道具有关.但是,我想通过在组件上创建样式继承来保持代码干燥.
我怎么能这样做?
感谢您的帮助!
解决方案
我相信我已经找到了我自己问题的答案(我仍然会将这个问题再开放几天如果可以改进).
为了传递样式,您可以添加global
";标记到样式化的 JSX 并使用 props.className
在组件中附加其他类名.
使用props.className
的父容器组件:
const Container = (props) =>(<><div className={`容器 ${props.className}`}>{props.children}
<样式jsx>{`.容器{宽度:100%;最大宽度:1200px;边距:0 自动;}`}</style></>)导出默认容器;
然后,当您想使用该组件时,您可以在
中使用 global
标志添加其他样式:
在标题中更多地使用和样式化容器:
从'./Container'导入容器;const Header = (props) =>(<><标题><Container className="header-col"><div><h1>{props.title}</h1>
<导航><ul><li>你好</li><li>那里</li></nav></容器></标题><样式 jsx 全局>{`.header-col{显示:弹性;对齐内容:间隔;}`}</style></>)导出默认标题;
虽然这不是 100% 完美(但在我看来它仍然很不错):
- 全局标志使您的样式具有全局性.所以其他组件可以使用这些风格(我相信)
- 你需要确保你的组件接受 props.className 来为这个全局样式附加额外的类名
I have created a Container component with component styles in next.js.
When I declare use of this container component throughout my site, I would like to add a className to it and subjectively style it depending on the context of its use.
Here is an example of my Container component:
const Container = (props) => (
<>
<div className="container">
{props.children}
</div>
<style jsx>{`
.container{
width: 100%;
max-width: 1200px;
margin: 0 auto;
}
`}</style>
</>
)
export default Container;
So, I want to give it a maximum width of 1200px, and centre it with auto margins. No problem, I have done that.
Now, I am planning to use this component in the header of my site. But in the case of the header, I would like the Container component to be a flexbox:
import Container from './Container'
const Header = (props) => (
<>
<header>
<Container className="header-col">
<div>
<h1>{props.title}</h1>
</div>
<nav>
<ul>
{/* Navigation items */}
</ul>
</nav>
</Container>
</header>
<style jsx>{`
.header-col{
display: flex;
justify-content: space-between;
}
`}</style>
</>
)
export default Header;
When I view the site, I noticed the flexbox style I specified for the Container component in the header is not present.
I was expecting the className to take effect, and allow me to add additional styles.
I believe this has something to do with it thinking that className is not a class name, rather props. But, I want to keep my code dry by creating style inheritance on components.
How could I do this?
Thanks for the help!
解决方案
I believe I have found the answer to my own question (I will still leave this question open for a couple more days just in case it can be improved).
In order to pass styles, you can add the "global
" flag to the styled JSX and append additional classnames in the component with props.className
.
Parent Container component using props.className
:
const Container = (props) => (
<>
<div className={`container ${props.className}`}>
{props.children}
</div>
<style jsx>{`
.container{
width: 100%;
max-width: 1200px;
margin: 0 auto;
}
`}</style>
</>
)
export default Container;
Then, when you want to use that component, you can add additional styles with the global
flag in the <style jsx>
:
Container being used and styled even more in the header:
import Container from './Container';
const Header = (props) => (
<>
<header>
<Container className="header-col">
<div>
<h1>{props.title}</h1>
</div>
<nav>
<ul>
<li>Hello</li>
<li>There</li>
</ul>
</nav>
</Container>
</header>
<style jsx global>{`
.header-col{
display: flex;
justify-content: space-between;
}
`}</style>
</>
)
export default Header;
This is not 100% perfect though (but in my opinion it is still pretty good):
- The global flag makes your styles global. So other components can use
these styles (I believe)
- You need to make sure your components take in props.className to append additional classnames for this global style
这篇关于样式化组件,两层 className - 如何在组件声明中应用样式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!