6

Background:

Let's say you have a simple page which has a logo and a heading only and one paragraph

<img src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png">
<h1>Foo Bar</h1>
<p>ABC12345</p>

This is how that looks like

enter image description here

That page, obviously would not have vertical overflow / scroll bar for almost even tiny scale mobile devices, let alone computers.

Question

How can you bring that heading to the top left of the screen and move the logo out of focus unless someone scrolls up? Open to using any JavaScript library and any CSS framework

Attempts:

  1. Tried using anchors but they only work if the page already had a scroll bar and anchor was out of focus.
  2. Tried window.scrollTo but that also requires the page to have scroll already
  3. Tried $("html, body").animate({ scrollTop: 90}, 100); but that also doesn't work when the page doesn't have overflow

Expected outcome:

Notes:

Please note that adding some extra <br/> to induce an overflow is not the way to go, it can be done that way but that's a very ordinary workaround

Why is it needed?

Its for a form for mobile devices, simple requirement is to take the first field of the form to top of the page and hide the logo (one can scroll up if they wish to see it) so it doesn't take attention away. Not using jQueryMobile for this particular task.

Hanky Panky
  • 46,730
  • 8
  • 72
  • 95
  • Use this $(window).scroll(function(){if($(window).scrollTop>"the height of your logo"){"Do your stuff here"}}); – Tyranicangel Apr 21 '14 at 11:56
  • You could use `media-queries` to detect if it is a small screen device. Hide the logo if devices are small. Then, Look for a `scroll` event and display the logo. – stackErr Apr 23 '14 at 14:48
  • I do not understand what you mean by "Tried window.scrollTo but that also requires the page to have scroll already" can you please clarify this? If you mean the page is not long enough to scroll, then you can look at my answer and I address that issue. – smilebomb Apr 23 '14 at 16:09

7 Answers7

5

If you want the user to be able to scroll up and see the logo, then the logo must be within the top boundary of the body tag, because anything outside of that tag will not be viewable. This means you cannot use negative margins or offsetting like that. The only way to achieve this is to have the page scroll to the desired location that is within the top boundary of the body tag. You can set the time for this event to one millisecond, but there will still be a 'jump' in the page when it is loaded. So, the logic is: first make sure the page is long enough to scroll to the right place, then scroll there.

//Change the jQuery selectors accordingly

//The minimum height of the page must be 100% plus the height of the image
$('body').css('min-height',$(document).height() + $('img').height());

//Then scroll to that location with a one millisecond interval
$('html, body').animate({scrollTop: $('img').height() + 'px'}, 1);

View it here.

Alternatively, you can load the page without the image in the first place. Then your form field will be flush with the top of the document. Then you could create the element at the top and similarly scroll the page again. This is a round-a-bout way of doing the same thing though. And the page will still 'jump,' there is no way around that.

smilebomb
  • 5,123
  • 8
  • 49
  • 81
  • @MiniRagnarok Yes, technically you're right, but that is semantic point. By 'jump' I mean the page will not start at the desired position. It is true that a scroll like that will make it appear smoother and nicer, however. – smilebomb Apr 23 '14 at 16:08
  • That's very kool :) I will give it a go with a full blown page and see how it goes, looks promising. – Hanky Panky Apr 23 '14 at 16:14
  • @jefffabiny I think you've misunderstood my comment. I like your answer, that's why I voted for it. The fiddle was only meant as an improvement. – MiniRagnarok Apr 23 '14 at 16:36
4

Only CSS and anchor link solution

With a pseudo element :

--- DEMO ---

First :

set : html,body{height:100%;}

Second :

Choose one of your existing tags. This tag mustn't have a relatively positioned parent (except if it is the body tag). Preferably the first element in the markup displayed after the logo. For your example it would be the h1 tag. And give it this CSS :

h1:before {
    content:"";
    position:absolute;
    height:100%;
    width:1px;
}

This creates an element as heigh as the viewport area. As it is displayed under the logo, the vertical scroll lenght is the same as the logo height.

Third :

Give the first element after logo an id (for this example I gave id="anchor").

Then you can use a link like this your_page_link#anchor and you will automaticaly scroll to the anchor (logo outside/above the viewport).

This works whatever height the logo is.

link to editable fiddle

Full code :

HTML

<img src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png">
 <h1 id="anchor">Foo Bar</h1>

<p>ABC12345</p> <a href="#anchor">Anchor link</a>

CSS

html, body {
    height:100%;
    margin:0;
    padding:0;
}
h1:before {
    content:"";
    position:absolute;
    width:1px;
    left:0;
    height:100%;
}
web-tiki
  • 99,765
  • 32
  • 217
  • 249
  • 1
    This one is nice as well, my only concern is that the page does not have only one div, I will try changing the css selector to use a specific div for that height and see how the others look – Hanky Panky Apr 23 '14 at 16:15
  • @Hanky웃Panky well, if you don't want to change the layout of your page you could use a dummy div with position:absolute : http://jsfiddle.net/webtiki/KrzP2/ – web-tiki Apr 23 '14 at 16:21
  • @Hanky웃Panky or even use a pseudo element on one of your existing tags : http://jsfiddle.net/webtiki/KrzP2/4/ I think I'll edit my post with this last solution as it avoids changing your markup and just add a few lines of CSS – web-tiki Apr 23 '14 at 16:23
  • 1
    That is nice, I like this answer as much as I like jeff's answer. Both are good. I'm going to try and see if I can award more bounty so that both of you get it if possible – Hanky Panky Apr 24 '14 at 06:55
  • @Hanky웃Panky that would be awesome:) – web-tiki Apr 24 '14 at 09:01
  • Hey, as per my word I tried to start a new bounty but I came to know that minimum for a second bounty is 200 reputation. Ummm sorry but I think you'll have to do with just an up-vote. Thanks for your answer – Hanky Panky Apr 24 '14 at 14:59
  • @Hanky웃Panky thank you very much, I wasn't sxpecting so much! – web-tiki Apr 26 '14 at 14:25
0

You might need to add js functionality to hide the logo if user scrolls down but I guess following code will fullfill the first requirement.
Please see

 <script src="js/jquery.js"></script>
 <img id='logo' src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png" style="display:none">
 <h1>Foo Bar</h1>
 <p>ABC12345</p>
 <script type="text/javascript">
  var p = $( "p:first" ); 
  var isScrolled=false;
   /* For Firfox*/
   $('html').on ('DOMMouseScroll', function (e) {
     isScrolled = true;
     if(p.scrollTop()==0 && isScrolled==true){
        $('#logo').css('display','block');
      }
   });
   /* For Chrome, IE, Opera and Safari: */
   $('html').on ('mousewheel', function (e) {
      isScrolled = true;
      if(p.scrollTop()==0 && isScrolled==true){
         $('#logo').css('display','block');
      }
   });
  </script>

I have referred this question to find solution.

Community
  • 1
  • 1
Yogesh
  • 928
  • 1
  • 8
  • 21
  • Hi Yogesh, thanks for your answer. Probably I could not phrase the question well, this is not what i'm looking for. – Hanky Panky Apr 21 '14 at 16:53
0

You could use touchmove event to detect swipe up or down. This is my example. You can try it on mobile device.

  <style>
  #logo {
    position: absolute;
    top: -100%;
    -webkit-transition: top 0.5s;
    -moz-transition: top 0.5s;
    -ms-transition: top 0.5s;
    -o-transition: top 0.5s;
    transition: top 0.5s;
  }
  #logo.show {
      top: 0;
  }
  </style>

  <script>
  var perY;
  var y;
  $(window).on('touchmove', function(e) {
    e.preventDefault();
    y = window.event.touches[0].pageY;
    if(!perY)
      perY = y;
    else
    {
      if(y > perY)
        $('#logo').addClass('show');
      else
        $('#logo').removeClass('show');
      perY = null;
    }
  });

  </script>


  <img id="logo" src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png">
  <h1>Foo Bar</h1>
  <p>ABC12345</p>
emn178
  • 1,474
  • 8
  • 12
0

This is the same problem i've encountered hiding the addressbar without the page overflowing. The only solution that fitted my needs was the following:

Set the min-height of the body to the viewportheight + your logo.

$('body').css('min-height', $(window).height() + 200);
Jos Gerrits
  • 245
  • 2
  • 11
0

This is a simple solution of getting the height of the contents to see if we can scroll to the part of the header, if not, we add height to the paragraph.

<img id="img" src="http://blog.stackoverflow.com/wp-content/uploads/StackExchangeLogo1.png" />
 <h1 id="h" >Foo Bar</h1>
<p id="par" style="background:yellow;">
   hello world
</p>

script:

function hola(){
   var imgH = $("#img").outerHeight(true);
   var titleH =  $("#h").outerHeight(true);
   var winH = $(window).height();
   var parH = $('#par').outerHeight(true);
   var contH = (imgH + titleH + parH);
   var wishH = (imgH + winH);
   console.log("wished height: " + wishH);
   console.log("window height: " + winH);
   console.log("content height: " + contH);
   if(contH < wishH){
    console.log("window is smaller than desired :(");
    var newH = wishH - contH;
    $("#par").height(parH + newH);
    $(window).scrollTop(imgH);
   }
}

Here is the working example: http://jsfiddle.net/Uup62/1/

rod_torres
  • 336
  • 2
  • 9
0

You may like this solution: http://jsfiddle.net/jy8pT/1/

HTML:

  <div class="addScroll"></div>
  <h1 class="logo"><img src="https://drupal.org/files/images/OQAAAI1PPrJY0nBALB7mkvju3mkQXqLmzMhxEjeb4gp8aujEUQcLfLyy-Sn4gZdkAas6-k8eYbQlGDE-GCjKfF5gIrUA15jOjFfLRv77VBd5t-WfZURdP9V3PdmT.png" height="100" alt="company logo"/></h1>

  <h2>This is a sample page heading.</h2>
  <p>This is a sample page text.</p>

JS:

function addScroll()
{
  $(".addScroll").css({
    "height": ($(window).height()+1) + "px",
    "width": "100%"
  });
}

$(document).ready(function(){
addScroll();
  $(window).resize(function(){
    addScroll();
  });
  $(window).scroll(function(){
     if($(window).scrollTop() > 0) 
     {
       $(".logo").animate({
         marginTop: "-110px"
       }, 500);
     }

      if($(window).scrollTop() == 0) 
     {
       $(".logo").animate({
         marginTop: "0"
       }, 500);
     }
  });
});

CSS:

body
{
    padding:0;
    margin:0;
}
h1.logo
{
  display:block;
  margin:0 0 10px 0;
  padding:0;
  outline:0;
}
.addScroll
{
  position:absolute;
  display:block;
  top:0;
  left:0;
  z-index:-1;
}
Mayank Tripathi
  • 1,346
  • 7
  • 21