Search code examples
cssmedia-queries

Trouble with media query and transitions


My goal is when the user gets into portrait mode an image will appear for a few seconds and then turn off.
I have tried visibility, width, height, display.It is not really a matter of setting a property as much as as it a timing thing. I can't seem to figure out how to switch a setting like visibility on going into portrait mode and then turn it off a few seconds later in pure CSS

Here are the specs

  • Pure CSS
  • Default so it is not showing.
  • In landscape mode it will never show.
  • In portrait mode it will show for a few seconds then disappear.
  • The outer most container div(with 'orientation' class) will be the div that gets the changes
  • (optional) once it has been on and then off make it so it will never turn again.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <title></title>
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">

  <style type="text/css">
    body {
      margin: 0;
      padding: 0;
    }
    .orientation {
      position: absolute;
      overflow: hidden;
      top: 0;
      left: 0;
      height: 100%;
      width: 100%;
      min-width: 200px;
      min-height: 200px;
    }
    .orientation .outerDiv {
      position: absolute;
      overflow: hidden;
      height: 100%;
      width: 100%;
    }
    .orientation .innerDiv {
      position: absolute;
      overflow: hidden;
      left: 50%;
      top: 50%;
      margin-left: -100px;
      margin-top: -100px;
      background-image: url('rotate.gif');
      background-repeat: no-repeat;
      width: 200px;
      height: 200px;
    }
    @media all and (orientation: portrait) {
      .orientation {}
    }
    @media all and (orientation: landscape) {
      .orientation {}
    }
  </style>

</head>

<body>
  <div class="orientation">
    <div class="outerDiv">
      <div class="innerDiv"></div>
    </div>
  </div>
</body>

</html>
</code>


Solution

  • You can do it using CSS3 animations. I made example on jsfiddle: https://jsfiddle.net/h532fxz4/ (reduce width of "result" box to make it like "portrait" view). Your code with my modifications looks now like below:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    
    <head>
        <title></title>
        <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
    
        <style type="text/css">
            body {
                margin: 0;
                padding: 0;
            }
            .orientation {
                position: absolute;
                overflow: hidden;
                top: 0;
                left: 0;
                height: 100%;
                width: 100%;
                min-width: 200px;
                min-height: 200px;
                opacity: 0;
            }
    
            .orientation .outerDiv {
                position: absolute;
                overflow: hidden;
                height: 100%;
                width: 100%;
            }
            .orientation .innerDiv {
                position: absolute;
                overflow: hidden;
                left: 50%;
                top: 50%;
                margin-left: -100px;
                margin-top: -100px;
                background-image: url('rotate.gif');
                background-repeat: no-repeat;
                width: 200px;
                height: 200px;
            }
    
            @-webkit-keyframes show-out {
                0% {
                    opacity: 1;
                }
                100% {
                    opacity: 0;
                }
            }
            @keyframes show-out {
                0% {
                    opacity: 1;
                }
                100% {
                    opacity: 0;
                }
            }
    
            @media all and (orientation: portrait) {
                .orientation {
                    opacity: 0;
                    animation-name: show-out;
                    animation-duration: 0.5s;
                     animation-delay: 2s;
                    animation-fill-mode: backwards;
                    animation-timing-function: linear;
                }
            }
            @media all and (orientation: landscape) {
                .orientation {}
            }
        </style>
    </head>
    <body>
        <div class="orientation">
            <div class="outerDiv">
                <div class="innerDiv"><img src="https://upload.wikimedia.org/wikipedia/en/2/21/EverestfromKalarPatarcrop.JPG" alt=""></div>
            </div>
        </div>
    </body> 
    </html>
    

    To clarify it:
    - show/hide property is "opacity" (it can be animated)
    - in media query "orientation: portrait" I added animation properties, where you can set time delay (when the effect of hiding image should start) and animation duration (how long transition should last).
    - keyframes (for webkit and other browsers), which define how opacity should change.
    - as far as I know it is impossible to "never show img again" in pure CSS without some JavaScript code.