In mobile terminal business development, fixed elements and input elements often exist at the same time in iOS. But fixed elements with soft keyboard evokes a lot of puzzling problems. This article provides a simple input box with fixed layout scheme.

Fixed + Input BUG in iOS

Let us first take a chestnut, the most intuitive explanation of the phenomenon of this BUG. For a regular fixed layout, the following layout may be used (the code below is only shown) :

    
    
        
    
    
    
    
        
    
    
    
    
        submit

The corresponding style is as follows:

header, footer, main {
    display: block;
}

header {
    position: fixed;
    height: 50px;
    left: 0;
    right: 0;
    top: 0;
}

footer {
    position: fixed;
    height: 34px;
    left: 0;
    right: 0;
    bottom: 0;
}

main {
    margin-top: 50px;
    margin-bottom: 34px;
    height: 2000px
}

And then it looks something like this. When I drag the page, the header and footer are already located in the corresponding position, so I can see that it is ok.

Fixed position

But then there’s the problem! If the soft keyboard in the bottom input box is aroused, slide the page again and you will see something like the following:

We see fixed elements scrolling along the page… Fixed property invalid!

Why is that? > After the soft keyboard is invoked, the fixed element of the page will become invalid (i.e. cannot float, can also be seen as becoming absolute position), so when the page is more than one screen and scrolling, the invalid fixed element will follow the scrolling.

This is the fixed element and input box bug on iOS. This is not limited to the type=text input box, any soft keyboard (such as date and time selection, select selection, etc.) is invoked, the same problem.

Although isscroll.js can solve the problem of fixed position scrolling very well, we try not to rely on third-party library layout scheme to simplify the implementation. Here is a reference.

Solution:

Since in iOS due to the soft keyboard called, the page fixed element will fail, leading to follow the page to scroll together, so if — the page will not be too long to scroll, so even if the fixed element fails, can not follow the page to scroll, there will be no problems above.

If the fixed element’s parent does not scroll, but moves the body scroll inside main, leaving header and footer unchanged, the code looks like this:

    
    
        
    
    
    
    
        
    
submit
header, footer, main { display: block; } header { position: fixed; height: 50px; left: 0; right: 0; top: 0; } footer { position: fixed; height: 34px; left: 0; right: 0; bottom: 0; } main {/* main: absolute; top: 50px; bottom: 34px; /* overflow-y: scroll; } main .content { height: 2000px; }

Let’s look at it again:

Fixed position

Under the original input method, the fixed element can be positioned in the correct position on the page. When you scroll the page, the footer doesn’t follow the page because you scroll inside the div inside main.

The above seems to solve the problem, but if you actually test it on the phone, you will find that scrolling inside the Main element is very awkward. When the sliding finger is released, scrolling immediately stops, and the original smooth scrolling feature is lost. Baidu the elastic scroll problem, found in WebKit, the following properties can restore elastic scroll.

-webkit-overflow-scrolling: touch;

Add this attribute to the main element and, well, that silky feeling is back!

*/ position: absolute; top: 50px; bottom: 34px; /* overflow-y: scroll; */ -webkit-overflow-scrolling: touch; }

In addition, the header and footer here use fixed positioning. If you consider that older iOS systems do not support fixed elements, you can completely replace fixed with absolute. The effect is the same after the test.

A fixed layout that does not rely on third-party libraries is now complete.

Under the Android layout

Speaking of iOS, let’s talk a little bit about the Android layout.

On Android2.3+, overflow-scrolling is not supported, so some browsers may not have smooth scrolling. However, the scrolling on the body is still very smooth, so it is ok to use the layout of fixed positioning, which was the first problem in iOS.

If you need to consider the following system Android2.3, because the fixed element is not supported, you still need to consider using isscroll.js to achieve internal scrolling.

In fact, the basic idea of fixed and input box is: > Because fixed will become invalid after the soft keyboard is aroused, it will scroll with the page when it can scroll. So if the page cannot scroll, then the fixed element will not scroll even if it fails, and there will be no bugs.

So you can think about solving the problem in this respect.

Some other details

In detail processing, in fact, there are many to pay attention to, pick a few actual encountered relatively big problems to say:

  1. Sometimes the soft keyboard blocks the input box after focus. Try scrollIntoView for the input element.
  2. When using third-party input methods in iOS, the input method will often cover the input field when evoked, and the input field will only appear after a text is entered. We don’t know of a good way to make the input field display correctly when invoked. This is an iOS pit for now.
  3. Some third-party browsers have a toolbar at the bottom that floats above the page, so the fixed position at the bottom is obscured by the toolbar. The solution is simple — adjust the distance of the fixed element from the bottom for different browsers.
  4. It’s a good idea to disable the TouchMove events for header and footer elements to prevent scrolling on them from triggering a partial full-screen browser mode switch, causing the top address bar and the bottom toolbar to block header and Footer elements.
  5. As you scroll to the top and bottom edges of the page, dragging will drag the entire View along, causing the page to “show the bottom”.

    Fixed position

In order to prevent the bottom of the page from showing, when the page is dragged to the edge, you can prevent the TouchMove event by judging the drag direction and whether it is an edge to prevent the page from continuing to drag.

Take the above inner scroll layout-scroll-fixed layout as an example, and give a code as a reference:

Var content = document.querySelector('main'); var startY; content.addEventListener('touchstart', function (e) { startY = e.touches[0].clientY; }); Content.addeventlistener (' touchMove ', function (e) {var status = '11'; var ele = this; var currentY = e.touches[0].clientY; If (ele.scrollTop === 0) {// Disable scrolling if the contents are smaller than the container status = ele.offsetheight >= ele.scrollHeight? '00' : '01'; } else if (ele.scrolltop + ele.scrollheight >= ele.scrollheight) {// If (ele.scrolltop + ele.scrollheight >= ele.scrollheight) } if (status ! Var direction = currenty-starty > 0? '10' : '01'; If (! = 0) {if (! = 0) {if (! (parseInt(status, 2) & parseInt(direction, 2))) { stopEvent(e); }}});