简体   繁体   English

React中的内联CSS styles:如何实现媒体查询?

[英]Inline CSS styles in React: how to implement media queries?

I quite like the inline CSS pattern ( video ) in React and i am thinking about using it.我非常喜欢 React 中的内联 CSS 模式视频),我正在考虑使用它。 However i have a question similar to this one .但是我有一个与此类似的问题。

How does one go about implementing media queries for an application using React's inline CSS pattern.一个 go 如何使用 React 的内联 CSS 模式为应用程序实现媒体查询。

You can't.你不能。 There are certain CSS features, like @media queries, that must be defined in a declaration block in a stylesheet.某些 CSS 功能,例如@media查询,必须在样式表的声明块中定义。

While inline CSS is great for most styling attributes that can be applied in key-value pairs, it isn't a complete replacement for dedicated stylesheets.虽然内联 CSS 非常适合大多数可应用于键值对的样式属性,但它并不能完全替代专用样式表。

EDIT:编辑:

There are experimental objects available in certain browsers (Chrome 9+, IE 10+, Firefox 6+) that allow you to add event listeners when media queries on the document change, such asMediaQueryList .在某些浏览器(Chrome 9+、IE 10+、Firefox 6+)中提供了实验性对象,允许您在文档上的媒体查询更改时添加事件侦听器,例如MediaQueryList

There is a nascent React project called Radium that provides mixins for applying conditional styling based on the active media queries, using MediaQueryList under the hood.有一个名为Radium的新兴 React 项目,它提供了 mixin,用于根据活动媒体查询应用条件样式,在MediaQueryList使用MediaQueryList

You can't do things like media queries and pseudo elements without a stylesheet.如果没有样式表,您将无法执行媒体查询和伪元素之类的操作。 You can, however, access the information they're built on in JavaScript.但是,您可以访问它们在 JavaScript 中构建的信息。 For example, a naive implementation of a resize mixin:例如,一个 resize mixin 的简单实现:

var ResizeMixin = {
    componentDidMount: function(){
        window.addEventListener('resize', this._resize_mixin_callback);
    },
    _resize_mixin_callback: function(){
        this.setState({
            viewport: {
                width: document.documentElement.clientWidth,
                height: document.documentElement.clientHeight
            }
        });
    },
    componentWillUnmount: function(){
        window.removeEventListener('resize', this._resize_mixin_callback);
    }
};

You could then include that in your component, and have a render that looks like this:然后你可以将它包含在你的组件中,并有一个看起来像这样的渲染:

render: function(){
  var style;

  if (this.state.viewport.width > 900) {
    style = {width: '45%', margin: '2.5%'};
  }
  else {
    style = {width: '100%', margin: '0'};
  }
  ...
}

I'm not sure this is a good idea, but it can be done.我不确定这是个好主意,但可以做到。


By 'naive implementation' I mean it has performance problems. “天真的实现”是指它存在性能问题。 addEventListener is actually pretty heavy, so you want to wrap that in a simple js event emitter. addEventListener 实际上很重,所以你想把它包装在一个简单的 js 事件发射器中。 You can also have only one instance of the viewport object to save some GC pressure.您也可以只有一个视口对象实例来节省一些 GC 压力。 And you want to throttle the event because browsers will emit it very fast when dragging the window.并且您想限制该事件,因为浏览器在拖动窗口时会非常快地发出它。

As with all good abstractions, you can make these optimizations when you have spare time, and you don't need to modify the components using it.与所有好的抽象一样,您可以在空闲时进行这些优化,并且不需要修改使用它的组件。

React-Responsive will let you use a certain use-case of media queries. React-Responsive将让您使用媒体查询的特定用例。

It lets you wrap react element elements with media specifications.它允许您使用媒体规范包装反应元素元素。 The wrapped elements will be rendered only if they media specification is met.包装的元素只有在满足媒体规范时才会呈现。 It's not a general-purpose solution because it doesn't let you add arbitrary css properties.这不是通用解决方案,因为它不允许您添加任意 css 属性。

Im late to the party but I still hope that I can help.我迟到了,但我仍然希望我能帮上忙。 You can use a "useMediaQuery" hook ( https://github.com/beautifulinteractions/beautiful-react-hooks/blob/master/src/useMediaQuery.js ) and then apply inline styles dynamically if the hook returns true.您可以使用“useMediaQuery”挂钩( https://github.com/beautifulinteractions/beautiful-react-hooks/blob/master/src/useMediaQuery.js ),然后如果挂钩返回true,则动态应用内联样式。

You can use media queries with the radium package by simply importing it and also using the StyleRoot component.您可以通过简单地导入它并使用 StyleRoot 组件来将媒体查询与镭包一起使用。

import Radium, { StyleRoot } from 'radium';

However keep it in mind, you can not use media queries directly under StyleRoot但是请记住,您不能直接在StyleRoot下使用媒体查询

, you will have to put the contents of StyleRoot on a separate component ,您必须将StyleRoot的内容放在单独的组件上

Worked for me below handy steps:在以下方便的步骤中为我工作:

  1. set a class for your desire item in media css file, for example例如,在媒体 css 文件中为您想要的项目设置 class

     @media (max-width: 768px){.sidebar-show{ display: block; }.sidebar-hide{ display: none; }}
  2. conditional rendering in your react, for example:( showSideBar is state variable for example)反应中的条件渲染,例如:(例如showSideBar是 state 变量)

     <aside className={`col-md-3 ${showSideBar?"sidebar-show":"sidebar-hide"}`}>

Well I dont know if this qualifies to be an answer but you can use it like 好吧,我不知道这是否有资格作为答案,但你可以使用它

<YourComponent style = { window.screen.width < 992 ? {width: "50%"} : {}/>

or 要么

 <YourComponent style = { window.screen.width > 1200 ? 
                          {width: "100%"} 
                          : window.screen.width > 991 ?
                               {width: "80%"}
                               : window.screen.width > 765 ? {width: "50%"}: {}/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM