简单的媒体查询规则在页面刷新时更改

Posted

技术标签:

【中文标题】简单的媒体查询规则在页面刷新时更改【英文标题】:Simple Media query rules change on page refresh 【发布时间】:2017-07-08 22:56:24 【问题描述】:

我有一个奇怪的问题。我的 CSS 中的媒体查询规则以它们应该的特定宽度触发,但是如果我已经将浏览器窗口调整到那个较小的宽度,然后将浏览器窗口扩展到它之外,就会发生一些奇怪的事情。在我刷新页面之前,一切看起来都很正常。只有在页面刷新时,布局才会以意想不到的方式发生变化。目标当然是让媒体查询正常运行,因为页面刷新不应该改变任何规则。

我试图用简单的骨骼重现问题:

//CSS media queries added to style tag here to prevent scrolling in other code blocks
var style = document.getElementsByTagName('style')[ 0 ];

style.innerhtml += 
'                                                                           \
  @media( max-width: 550px )                                               \
    body                                                                   \
      background-color: #ddd;                                               \
      transition: 1s;                                                       \
                                                                           \
    main                                                                   \
      height: auto;                                                         \
      text-align: center;                                                   \
                                                                           \
    .circle, .about-container                                              \
      float: none;                                                          \
                                                                           \
    .circle                                                                \
      display: inline-block;                                                \
      transform: translateY( 0 );                                           \
                                                                           \
    .about-container                                                       \
      margin: 0 auto;                                                       \
      text-align: left;                                                     \
                                                                           \
                                                                           \
  @media( min-width: 551px )                                               \
    .circle                                                                \
      transform: translateY( 0 );                                           \
                                                                           \
                                                                           \
';
/* ///////////////// ELEMENTS IN ORDER THEY APPEAR IN HTML ///////////////// */
* 
  box-sizing: border-box;

main 
  max-width: 600px;
  height: 11rem;
  margin: 0 auto;
  padding-top: 10px;
  font-size: 0.8rem;
  text-align: left;


.circle 
  width: 100px;
  height: 100px;
  background-color: #444;
  border-radius: 50%;
  float: left;
  top: calc( 50% - 10px );


.about-container 
  width: 75%;
  float: right;


body button 
  display: block;
  margin: 0 auto;
  padding: 8px;
<head>
  <style>
  
    /* ///////////// BASIC STYLES TO MAKE THIS SNIPPET LOOK BETTER ///////////// */
    @import url('https://necolas.github.io/normalize.css/latest/normalize.css');
    
    .clearfix:after 
      content: "";
      display: block;
      clear: both;
    
    .vertically-center 
      position: relative;
      top: 50%;
      transform: translateY( -50% );
    
  </style>
</head>
<body>
  <main class="clearfix">
    <div class="circle vertically-center"></div>
    <div class="about-container">
      <h3>About</h3>
      <p>
        This problem is wierd. When <strong>snippet is made full screen</strong> 
        and browser width is shrunk to less than <strong>550px</strong> <em>
        ( You will know you're at 550px because the background will darken )</em> 
        the layout changes - as expected. However when window is expanded beyond 
        550px again and <strong>Reload Frame</strong> is clicked the layout 
        unexpectedly updates itself. <br><br>What's going on?
      </p>
    </div>
  </main>
  <button onclick="location.reload()">Reload Frame</button>
</body>

虽然很奇怪,但我觉得这有一个简单的解决方案,我希望?

编辑:我在 chrome 浏览器上看到了这些结果。将上传一个 GIF 来演示我在下面看到的内容。

【问题讨论】:

你 1) 翻到整页 2) 缩小宽度直到背景变暗。 3)扩大宽度,直到背景为白色。 4) 点击按钮? 你用的是什么浏览器? 铬。我正在上传一个 gif 来演示我所看到的。 @MrLister 我的问题不是 javascript 问题。这是刷新时触发的 CSS 媒体查询。这里的 JavaScript 仅用于这个演示。 @L.S 请查看带有显示我的问题的 gif 更新。 【参考方案1】:

Chrome 似乎对同时浮动、定位和翻译的元素存在问题。同样,这是 Chrome 中的缺陷,而不是您的代码中的缺陷。 解决这个问题的一种方法是不使用定位,只使用平移来移动圆。

//CSS media queries added to style tag here to prevent scrolling in other code blocks

var style = document.getElementsByTagName('style')[ 0 ];

style.innerHTML += 
'                                                                           \
  @media( max-width: 550px )                                               \
    body                                                                   \
      background-color: #ddd;                                               \
                                                                           \
    main                                                                   \
      height: auto;                                                         \
      text-align: center;                                                   \
                                                                           \
    .circle, .about-container                                              \
      float: none;                                                          \
                                                                           \
    .circle                                                                \
      display: inline-block;                                                \
      transform: translateY(-40%); /* changed a bit to compensate */        \
                                                                           \
    .about-container                                                       \
      margin: 0 auto;                                                       \
      text-align: left;                                                     \
                                                                           \
                                                                           \
';
/* ///////////////// ELEMENTS IN ORDER THEY APPEAR IN HTML ///////////////// */

body 
  transition: 0.25s;


main 
  max-width: 600px;
  margin: 0 auto;
  height: 11rem;
  padding-top: 10px;
  font-size: 0.8rem;
  text-align: left;


.circle 
  height: 100px;
  width: 100px;
  background-color: #444;
  border-radius: 50%;
  float: left;

/* this was moved here */
.vertically-center 
  transform: translateY(40%);


.about-container 
  width: 75%;
  float: right;


body button 
  display: block;
  margin: 0 auto;
  padding: 8px;
<head>
  <style>
    /* ///////////// BASIC STYLES TO MAKE THIS SNIPPET LOOK BETTER ///////////// */
    @import url('https://necolas.github.io/normalize.css/latest/normalize.css');
    * 
      box-sizing: border-box;
    
    .clearfix:after 
      content: "";
      display: block;
      clear: both;
    
    /* moved the .vertically-center bit to before the media query */
  </style>
</head>
<body>
  <main class="clearfix">
    <div class="circle vertically-center"></div>
    <div class="about-container">
      <h3>About</h3>
      <p>
        This problem is pretty wierd. When you
        <strong>make this snippet full screen</strong> and try shrinking the browser
        width to less than <strong>550px</strong> <em>( You will know you're at 550px
        because the background will darken )</em> the layout changes - Which is 
        expected. However when you expand the window beyond 550px again and click 
        <strong>Reload Frame</strong> the current layout unexpectedly updates
        itself. <br><br>What's going on?
      </p>
    </div>
  </main>
  <button onclick="location.reload()">Reload Frame</button>
</body>

但正如其他人所展示的,还有更多的解决方案。任君挑选!

【讨论】:

感谢您指出这是 Chrome 中的浏览器怪癖。我最初甚至没想过要检查这一点。我做了更多的测试,似乎transform 属性对带来这个问题没有影响。它是定位元素和浮动。删除其中任何一个并修复问题。我喜欢你的解决方案。做更多的测试。 我找到了一个更简单的解决方案,请看我的回答。【参考方案2】:

解决方案: 简单的解决方案是将margin-top:11% 添加到div.vertically-center,然后在调整窗口大小后圆圈恢复到原来的状态..! :D

修复 CSS 问题有很多方法可以修复,甚至可以通过添加一些 html 元素以及 css 代码或仅通过更改当前 css 而不添加任何元素来修复它。所以这取决于你哪一个那就跟着吧。

更好的使用方法: 由于我检查了margin-top:11% 与 Firefox 样式相混淆,因此您可以使用以下两种方法将其仅应用于 Chrome:

1) Chrome JavaScript 解决方案:

if (navigator.appVersion.indexOf("Chrome/") != -1) 
document.getElementById("vertically-center").style.marginTop = "11%";

2) Chrome CSS 解决方案:

/* Chrome 29+ */
@media screen and (-webkit-min-device-pixel-ratio:0)
  and (min-resolution:.001dpcm) 
   .vertically-center  margin-top:11%; 


/* Chrome 22-28 */
@media screen and(-webkit-min-device-pixel-ratio:0) 
  .selector -chrome-:only(; 
     property:value;
  ); 

【讨论】:

【参考方案3】:

更新代码 试试这个运行代码

<div class="circlemain">
   <div class="circle vertically-center"></div>
</div>

   .circlemain 
        top: 50%;
        position: relative;
    

@media( max-width: 550px )   
    .vertically-center 
     position: relative;
     transform: translateY( 0% ) !important;
     top: 50%;
 

//CSS media queries added to style tag here to prevent scrolling in other code blocks

    var style = document.getElementsByTagName('style')[ 0 ];

    style.innerHTML += 
    '                                                                           \
      @media( max-width: 550px )                                               \
        body                                                                   \
          background-color: #ddd;                                               \
                                                                               \
        main                                                                   \
          height: auto;                                                         \
          text-align: center;                                                   \
                                                                               \
        .circle, .about-container                                              \
          float: none;                                                          \
                                                                               \
        .circle                                                                \
          display: inline-block;                                                \
          transform: translateY( 0 );                                           \
                                                                               \
        .about-container                                                       \
          margin: 0 auto;                                                       \
          text-align: left;                                                     \
                                                                               \
                                                                               \
      @media( min-width: 551px )                                               \
        .circle                                                                \
          transform: translateY( 0 );                                           \
                                                                               \
                                                                               \
    ';
/* ///////////////// ELEMENTS IN ORDER THEY APPEAR IN HTML ///////////////// */

    main 
      max-width: 600px;
      margin: 0 auto;
      height: 11rem;
      padding-top: 10px;
      font-size: 0.8rem;
      text-align: left;
    
.circlemain 
    top: 50%;
    position: relative;

    .circle 
      height: 100px;
      width: 100px;
      background-color: #444;
      border-radius: 50%;
      float: left;
      top: calc( 50% - 10px );
    

    .about-container 
      width: 75%;
      float: right;
    

    body button 
      display: block;
      margin: 0 auto;
      padding: 8px;
    
    @media( max-width: 550px )   
    .vertically-center 
        position: relative;
        transform: translateY( 0% ) !important;
        top: 50%;
    
    
     
<head>
      <style>
        /* ///////////// BASIC STYLES TO MAKE THIS SNIPPET LOOK BETTER ///////////// */
        @import url('https://necolas.github.io/normalize.css/latest/normalize.css');
        * 
          box-sizing: border-box;
        
        .clearfix:after 
          content: "";
          display: block;
          clear: both;
        
        .vertically-center 
          position: relative;
          top: 50%;
          transform: translateY( -50% );
        
      </style>
    </head>
    <body>
      <main class="clearfix">
        <div class="circlemain">
        <div class="circle vertically-center"></div>
</div>
        <div class="about-container">
          <h3>About</h3>
          <p>
            This problem is pretty wierd. When you
            <strong>make this snippet full screen</strong> and try shrinking the browser
            width to less than <strong>550px</strong> <em>( You will know you're at 550px
            because the background will darken )</em> the layout changes - Which is 
            expected. However when you expand the window beyond 550px again and click 
            <strong>Reload Frame</strong> the current layout unexpectedly updates
            itself. <br><br>What's going on?
          </p>
        </div>
      </main>
      <button onclick="location.reload()">Reload Frame</button>
    </body>

【讨论】:

您能解释一下为什么会这样吗,OP 的代码有什么问题,以及如何解决这个问题?顺便说一句,这个 sn-p 的行为与窄窗口中的 OP 不同。【参考方案4】:

因此,感谢先前的答案指出这是 chrome 中的浏览器怪癖。然而,没有一个解决方案尽可能简单。我发现关键问题是@media( max-width: 550px ) 媒体查询下的display: inline-block。我删除了它,将其更改为 display: block 并添加了 margin: 0 auto 以使圆圈居中,因为它不再受其父级上的 text-align: center 规则的影响。这对我来说以最简单的方式解决了这个问题。这是sn-p:

//CSS media queries added to style tag here to prevent scrolling in other code blocks
var style = document.getElementsByTagName('style')[ 0 ];

style.innerHTML += 
'                                                                           \
  @media( max-width: 550px )                                               \
    body                                                                   \
      background-color: #ddd;                                               \
      transition: 1s;                                                       \
                                                                           \
    main                                                                   \
      height: auto;                                                         \
      text-align: center;                                                   \
                                                                           \
    .circle, .about-container                                              \
      float: none;                                                          \
                                                                           \
    .circle                                                                \
      display: block; /* changed display: inline-block to display: block */ \
      margin: 0 auto; /* added this line to recenter the circle */          \
      transform: translateY( 0 );                                           \
                                                                           \
    .about-container                                                       \
      margin: 0 auto;                                                       \
      text-align: left;                                                     \
                                                                           \
                                                                           \
  @media( min-width: 551px )                                               \
    .circle                                                                \
      transform: translateY( 0 );                                           \
                                                                           \
                                                                           \
';
/* ///////////////// ELEMENTS IN ORDER THEY APPEAR IN HTML ///////////////// */
* 
  box-sizing: border-box;

main 
  max-width: 600px;
  height: 11rem;
  margin: 0 auto;
  padding-top: 10px;
  font-size: 0.8rem;
  text-align: left;


.circle 
  width: 100px;
  height: 100px;
  background-color: #444;
  border-radius: 50%;
  float: left;
  top: calc( 50% - 10px );


.about-container 
  width: 75%;
  float: right;


body button 
  display: block;
  margin: 0 auto;
  padding: 8px;
<head>
  <style>
  
    /* ///////////// BASIC STYLES TO MAKE THIS SNIPPET LOOK BETTER ///////////// */
    @import url('https://necolas.github.io/normalize.css/latest/normalize.css');
    
    .clearfix:after 
      content: "";
      display: block;
      clear: both;
    
    .vertically-center 
      position: relative;
      top: 50%;
      transform: translateY( -50% );
    
  </style>
</head>
<body>
  <main class="clearfix">
    <div class="circle vertically-center"></div>
    <div class="about-container">
      <h3>About</h3>
      <p>
        This problem is wierd. When <strong>snippet is made full screen</strong> 
        and browser width is shrunk to less than <strong>550px</strong> <em>
        ( You will know you're at 550px because the background will darken )</em> 
        the layout changes - as expected. However when window is expanded beyond 
        550px again and <strong>Reload Frame</strong> is clicked the layout 
        unexpectedly updates itself. <br><br>What's going on?
      </p>
    </div>
  </main>
  <button onclick="location.reload()">Reload Frame</button>
</body>

【讨论】:

以上是关于简单的媒体查询规则在页面刷新时更改的主要内容,如果未能解决你的问题,请参考以下文章

下一个 JS apollo 链接更改清除查询,必须刷新页面才能运行查询

React页面不会在url查询更改时重新呈现

更改查询字符串而不重新加载/刷新[重复]

PHP:检测页面刷新

Rails 页面在每次刷新时更改翻译

键盘输入时,如何在Ajax调用URL更改后停止MVC页面刷新