我开始用styled-components编写自己的设计系统。但是我一直在努力使组件具有响应能力。
// Container.tsx
import React from 'react'
import styled from 'styled-components'
import { media } from '../utils/mediaQuery'
export const StyledContainer = (isFluid: boolean) => {
return styled(
({ element: Component, containerRef, ...props }) => {
console.log(isFluid)
return (
<Component ref={containerRef} {...props}>
{props.children}
</Component>
)
}
)`
width: 100%; /* Fix component tight to center*/
margin-right: auto;
margin-left: auto;
padding-right: ${({ theme }) => theme.container.paddingX}rem;
padding-left: ${({ theme }) => theme.container.paddingX}rem;
${isFluid ? '' : media.xl`max-width: 1040px;`}
${isFluid ? '' : media.lg`max-width: 960px;`}
${isFluid ? '' : media.md`max-width: 720px;`}
${isFluid ? '' : media.sm`max-width: 576px;`}
`
}
type CProps = {
fluid?: boolean
element?: React.Component | string
children: React.ReactNode | React.ReactNode[]
}
const Container = React.forwardRef(
(props: CProps, ref: React.Ref<HTMLElement>) => {
const { fluid = false, children, element = 'div' } = props
const BaseContainer = StyledContainer(fluid)
return (
<BaseContainer element={element} containerRef={ref}>
{children}
</BaseContainer>
)
}
)
export default Container
// ../../utils/mediaQuery
import {
css,
SimpleInterpolation,
CSSObject,
FlattenSimpleInterpolation,
} from 'styled-components'
export const breakpoints: { [key: string]: number } = {
xl: 1200,
lg: 992,
md: 768,
sm: 576,
xs: 376
}
export const media = Object.keys(breakpoints).reduce(
(
accumulator: {
[key: string]: (
styles: CSSObject | TemplateStringsArray,
...interpolations: SimpleInterpolation[]
) => FlattenSimpleInterpolation
},
label: string
) => {
const size = breakpoints[label]
Object.assign(accumulator, {
[label]: (
styles: CSSObject | TemplateStringsArray,
...interpolations: SimpleInterpolation[]
) => css`
@media screen and (min-width: ${size}px) {
${css(styles, ...interpolations)}
}
`
})
return accumulator
},
{}
)
一切正常。所有CSS都捆绑成块文件,控制台上没有错误或错误出现。我的预期结果是媒体查询值的顺序,该组件的屏幕尺寸后面紧跟max-width
。但是我的实际结果是@media screen and (min-width: 576px) {...}
,它与${isFluid ? '' : media.sm`max-width: 576px;`}
捆绑在一起,覆盖了其他查询。有什么想法吗?
答案 0 :(得分:0)
尝试颠倒媒体查询定义的顺序:
${isFluid ? '' : media.sm`max-width: 576px;`}
${isFluid ? '' : media.md`max-width: 720px;`}
${isFluid ? '' : media.lg`max-width: 960px;`}
${isFluid ? '' : media.xl`max-width: 1040px;`}
因此,最终的CSS将是:
media screen and (min-width: 576px) {...}
media screen and (min-width: 720px) {...}
media screen and (min-width: 960px) {...}
media screen and (min-width: 1040px) {...}
对于CSS媒体查询,您首先需要最小的min-width
定义。
最后一个min-width: 576px
之前,这意味着576px
上方的任何屏幕都将采用该样式。
此Stackoverflow answer解释了原因。