Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Media query rules change on page refresh

I have a strange problem. Media query rules in my CSS trigger at a certain widths like they are supposed to, however if I already resized the browser window to that smaller width, then expand the browser window beyond it something odd happens. Things appear normal until I refresh the page. The layout changes in an unexpected way only on page refresh. The goal of course is for the media queries to behave normally as in a page refresh shouldn't change any rules.

I tried to recreate the problem using the bare bones:

//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>

Though weird I have a feeling this has a simple solution, I hope?

Edit: I'm seeing these results on the chrome browser. Will upload a GIF that demonstrates what I see below.

enter image description here

like image 593
sol acyon Avatar asked Feb 19 '17 18:02

sol acyon


People also ask

Why do media queries need to be placed after the traditional CSS rules?

Basically you are using media queries when you want to apply CSS styles depending on a device's general type (such as print vs. screen), specific characteristics (such as the width of the browser viewport, or environment (such as ambient light conditions).

How do you set a minimum and maximum media query?

Max-width and min-width can be used together to target a specific range of screen sizes. @media only screen and (max-width: 600px) and (min-width: 400px) {...} The query above will trigger only for screens that are 600-400px wide. This can be used to target specific devices with known widths.

What does @media do in CSS?

The @media CSS at-rule can be used to apply part of a style sheet based on the result of one or more media queries. With it, you specify a media query and a block of CSS to apply to the document if and only if the media query matches the device on which the content is being used.

How do I set up multiple media queries?

You may use as many media queries as you would like in a CSS file. Note that you may use the and operator to require multiple queries to be true, but you have to use the comma (,) as the or operator to separate groups of multiple queries. The not keyword can be used to alter the logic as well.


2 Answers

It looks like Chrome has a problem with elements that are floated, positioned and translated at the same time. Again, this is a flaw in Chrome, not in your code.
One way out of this is to use no positioning, only translation to move the circle.

//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>

But as others have shown, there are more solutions. Take your pick!

like image 59
Mr Lister Avatar answered Oct 19 '22 11:10

Mr Lister


Solution : The simple solution is to add margin-top:11% to div.vertically-center then the circle comes back to it's original state after resizing the window back..! :D

And fixing a CSS issue has lots of ways to be fixed it can even be fixed with just adding some html elements along with css code or just by changing the current css and without adding any elements.So it's up to you which one to follow then.

BETTER WAY TO USE IT : Since I checked that the margin-top:11% messes up with Firefox style so you can use following two ways to just apply it to Chrome only as :

1) Chrome JavaScript Solution :

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

2) Chrome CSS Solution :

/* 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;
  );} 
}
like image 23
Umair Shah Yousafzai Avatar answered Oct 19 '22 09:10

Umair Shah Yousafzai