- CSS и iOS Safari
- Свойства
- Фиксы
- Выводы
- position: fixed doesn’t work on iPad and iPhone
- 16 Answers 16
- Safari Viewport Bug, Issues with Fixed Position and Bottom or Top
- Portrait Mode
- Landscape Mode
- Crappy «Workaround» for Portrait Mode
- Does anybody out there have any idea what is happening?
- Anybody aware of any workarounds?
- Anybody aware of an actual solution?
- 1 Answer 1
CSS и iOS Safari
Всегда хочется, что бы твой сайт выглядел одинаково хорошо на разных устройствах, включая и мобильные. Но, если поведение в браузерах Android во многом предсказуемо, то с iOS возникает ряд «сюрпризов». О них сегодня и поговорим!
Часть примеров уже публиковалась на Хабре, но я все-равно решил включить их в статью. Разделю статью на две части. В первой – приведу список полезных css-свойств для webkit, а во второй поговорим о фиксах проблем, возникающих при версте для iOS Safari.
Свойства
1. -webkit-overflow-scrolling: touch
Это css-свойство добавит плавный скролл в блоках с overflow: scroll. Рекомендую добавлять это свойство везде, где внутри блока может возникать прокрутка, к примеру, в мобильном меню.
2. -webkit-text-size-adjust: none
Отключает масштабирование текста в горизонтальной ориентации.
3. -webkit-tap-highlight-color: #ccc
Устанавливает цвет выделения активного элемента при тапе на нем (a, label). По умолчанию это серый цвет, и часто может быть ни к чему, или выбиваться из общего дизайна.
Пример такого выделения:
4. -webkit-appearance: none
Отключает наложение на элементы стилей системы: тени, border-radius и т.д. Применяется для input (но не всех), textarea, и т.д. Удобно, когда надо задать единый вид элементов на всех устройствах.
Применяется не только в верстке для Safari.
Данный медиа-запрос позволит отдельно прописывать стили только для устройств, с поддержкой тач. Таким образом, на тач-устройствах можно отключить лишние анимации, ненужные данным типам устройств.
Можно использовать не только в верстке для Safari.
Фиксы
1. background-attachment: fixed
Проблема: background-attachment: fixed не работает в iOS Safari.
Решение: Фиксировать не фон, а блок или псевдоэлемент.
2. Нежелательный скролл модального окна
Проблема: Это довольно редкий случай, но для общей информации, думаю, так же полезно будет знать о нем. Если модальное окно имеет собственную прокрутку и в закрытом состоянии просто установлен отрицательный z-index (и, к примеру, opacity: 0) — то при попытке скролла страницы, модальное окно может перехватить скролл. В результате чего не будет осуществляться прокрутка страницы.
Решение: Добавляем pointer-events: none к модальному окну в закрытом состоянии.
3. Пропадание меню при скролле
Для того, что бы меню «прилипало» к верхней границе экрана при скролле страницы, часто используют следующий прием. Изначально у меню установлено свойство position: absolute, и при достижении верхней границы окна, через js оно меняется на fixed. А при скролле страницы к началу, значение опять меняется на absolute.
Проблема: В Safari на iOS, при смене position с fixed на absolute, меню пропадает с экрана пока скролл не завершится.
Решение: Использовать для меню position: -webkit-sticky. Поведение меню будет сравнимо с вышеописанным, но пропадать ничего не будет! Плюс, не надо использовать js
К слову, значение sticky для свойства position сейчас поддерживается большим количеством браузеров, поэтому его можно использовать и в десктопных браузерах.
4. Блок с position: fixed при скролле
Если реализации решений предыдущих проблем я видел на некоторых сайтах, то данная проблема на сайтах встречается постоянно.
Проблема: При скролле в браузере изменяется высота экрана. Отсюда, если при раскрытом меню или модальном окне не блокировать скролл, возникает подобный эффект:
Решение: Нужно сделать следующий «трюк», используя transform.
Величина в 70px покрывает разницу в изменении высоты окна. И только transform позволяет прорисовывать фон элемента за пределами экрана в данной ситуации.
Выводы
А выводов особо нет, просто пользуйтесь ) Если знаете еще полезные css-свойства или «фиксы», применимые на практике, пишите в комментариях!
Спасибо за внимание!
Update
В свойствах изменен пункт 5. Т.к. media (hover) имеет узкую поддержку. Спасибо dom1n1k за ценное замечание.
Источник
position: fixed doesn’t work on iPad and iPhone
I have been struggling with fixed positioning in iPad for a while. I know iScroll and it does not always seem to work (even in their demo). I also know that Sencha has a fix for that, but I couldn’t Ctrl + F the source code for that fix.
I am hoping that someone may have the solution. The problem is that fixed positioned elements do not get updated when the user pans down/up on an iOS powered mobile Safari.
16 Answers 16
A lot of mobile browsers deliberately do not support position:fixed; on the grounds that fixed elements could get in the way on a small screen.
The Quirksmode.org site has a very good blog post that explains the problem: http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html
Also see this page for a compatibility chart showing which mobile browsers support position:fixed; : http://www.quirksmode.org/m/css.html
(but note that the mobile browser world is moving very quickly, so tables like this may not stay up-to-date for long!)
Update: iOS 5 and Android 4 are both reported to have position:fixed support now.
I tested iOS 5 myself in an Apple store today and can confirm that it does work with position fixed. There are issues with zooming in and panning around a fixed element though.
I found this compatibility table far more up to date and useful than the quirksmode one: http://caniuse.com/#search=fixed
It has up to date info on Android, Opera (mini and mobile) & iOS.
Fixed positioning doesn’t work on iOS like it does on computers.
Imagine you have a sheet of paper (the webpage) under a magnifying glass(the viewport), if you move the magnifying glass and your eye, you see a different part of the page. This is how iOS works.
Now there is a sheet of clear plastic with a word on it, this sheet of plastic stays stationary no matter what (the position:fixed elements). So when you move the magnifying glass the fixed element appears to move.
Alternatively, instead of moving the magnifying glass, you move the paper (the webpage), keeping the sheet of plastic and magnifying glass still. In this case the word on the sheet of plastic will appear to stay fixed, and the rest of the content will appear to move (because it actually is) This is a traditional desktop browser.
So in iOS the viewport moves, in a traditional browser the webpage moves. In both cases the fixed elements stay still in reality; although on iOS the fixed elements appear to move.
The way to get around this, is to follow the last few paragraphs in this article
(basically disable scrolling altogether, have the content in a separate scrollable div (see the blue box at the top of the linked article), and the fixed element positioned absolutely)
«position:fixed» now works as you’d expect in iOS5.
position: fixed does work on android/iphone for vertical scrolling. But you need to make sure your meta tags are fully set. e.g
Also if you’re planning on having the same page work on android pre 4.0, you need to set the top position also, or a small margin will be added for some reason.
now apple support that
I had this problem on Safari (iOS 10.3.3) — the browser was not redrawing until the touchend event fired. Fixed elements did not appear or were cut off.
The trick for me was adding transform: translate3d(0,0,0); to my fixed position element.
EDIT — I now know why the transform fixes the issue: hardware-acceleration. Adding the 3D transformation triggers the GPU acceleration making for a smooth transition. For more on hardware-acceleration checkout this article: http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css.
Fixed Footer (here with jQuery):
Avoid on the same box using transform:— and position:fixed. Element will stay in position:static if there is any transform.
We now have a solid re-write that provides true fixed toolbars on the a lot of popular platforms and safely falls back to static toolbar positioning in other browsers.
The coolest part about this approach is that, unlike JS-based solutions that impose the unnatural scrolling physics across all platforms, our scrolling feels 100% native because it is. This means that scrolling feels right everywhere and works with touch, mousewheel and keyboard user input. As a bonus, our CSS-based solution is super lightweight and doesn’t impact compatibility or accessibility.
The simple way to fix this problem just types transform property for your element. and it will be fixed. Happy Coding 🙂
Also you can try his way as well this is also work fine.
using jquery i am able to come up with this. it doesnt scroll smooth, but it does the trick. you can scroll down, and the fixed div pops up on top.
Finally we want to determine if the ipod touch in landscape or portrait mode to display accordingly
Even though the CSS attribute
Safari on iPad and Safari on iPhone do not have resizable windows. In Safari on iPhone and iPad, the window size is set to the size of the screen (minus Safari user interface controls), and cannot be changed by the user. To move around a webpage, the user changes the zoom level and position of the viewport as they double tap or pinch to zoom in or out, or by touching and dragging to pan the page. As a user changes the zoom level and position of the viewport they are doing so within a viewable content area of fixed size (that is, the window). This means that webpage elements that have their position «fixed» to the viewport can end up outside the viewable content area, offscreen.
What is ironic, Android devices do not seem to have this issue. Also it is entirely possible to use
I found the root cause of this quirk; that it is the scroll event not playing nice when used in conjunction with the HTML or BODY tag. Sometimes it does not like to fire the event, or you will have to wait until the scroll swing event is finished to receive the event. Specifically, the viewport is re-drawn at the end of this event and fixed elements can be re-positioned somewhere else in the viewport.
So this is what I do: (avoid using the viewport, and stick with the DOM!)
In essence this will cause the BODY to be the size of the viewport and non-scrollable. The scrollable DIV nested inside will scroll as the BODY normally would (minus the swing effect, so the scrolling does stop on touchend.) The fixed DIV stays fixed without interference.
As a side note, a high z-index value on the fixed DIV is important to keep the scrollable DIV appear to be behind it. I normally add in window resize and scroll events also for cross-browser and alternate screen resolution compatibility.
If all else fails, the above code will also work with both the fixed and scrollable DIVs set to
Источник
Safari Viewport Bug, Issues with Fixed Position and Bottom or Top
I’m experiencing something strange in iOS 12.3.1 Safari. This issue dates back to at least iOS 12.2, but I imagine it’s been a problem for much longer than that.
The issue manifests itself when trying to align an element to the bottom axis of the viewport, and is a problem in both portrait and landscape mode.
In order to reproduce the problem, the element must have a position of fixed or absolute , yet it doesn’t matter whether you position the element with top and transform or bottom .
Portrait Mode
The issue only manifests itself in portrait mode if Safari is displaying its condensed URL bar, which replaces the normal URL and menu bars, and there is no vertical overflow.
Normal URL and Menu Bars // Condensed URL Bar
Notably, the condensed menu bar is only ever displayed when there is either vertical overflow and the browser is scrolled downwards or when the browser’s orientation has been changed from portrait to landscape and then back again (despite whether or not there is vertical overflow).
Changing Orientation with Vertical Overflow // Without Overflow
I’m not sure exactly what’s happening here.
Landscape Mode
The issue with landscape mode always and only occurs when the normal navigation bar is displayed at the top of the page. The navigation bar is only ever hidden in landscape mode due to downward scrolling or orientation change from portrait to landscape.
With Vertical Overflow
Without Vertical Overflow
What’s interesting is that the height of the navigation bar in landscape mode clearly offsets the viewport so that position of bottom: 0 or top: 100% is pushed outside of the viewport when the navigation bar is being displayed.
Crappy «Workaround» for Portrait Mode
It’s a super hack-ish workaround, and a crappy workaround at that, but it’s the only thing so far that causes position: fixed; bottom: 0; to actually position an element at the bottom of the viewport after switching orientations if there is no overflow.
However, I just noticed that it creates an invisible vertical overflow and thus unnecessary vertical scrolling in at least Safari and Chrome. I’m also worried that it might cause other issues on other devices in other browser that I’m unable to test.
It absolutely sucks that a website has to sometimes look like crap for the sake of user-experience due to this bug.
Does anybody out there have any idea what is happening?
Anybody aware of any workarounds?
Anybody aware of an actual solution?
1 Answer 1
Hello this question kind of got me at first and I thought back to my days poking around in HTML and CSS for hours on end trying to get things right. Alas all those hours of missery have been for this moment.
vh used to be calculated by the current viewport of your browser. If you loaded a site in your browser, 1vh would be the same as 1% of your screen height, and then minus the browser interface.
But! If you wanted to scroll, it gets tricky. Once you brush past the browser interface (in this case your address bar), you would have a wierd jump in your content because the vh would be updated.
Safari for iOS was actually was one of the first to implement a fix. They set a fixed vh value based on the max screen height. Then the user wouldn’t experience the jump in content, but . yup, there’s always a but.
Having the fixed value is awesome, except when you wanna have a full sized element, or an element with fixed position at the bottom of the screen because then it would get cropped out!
That is your problem. and say goodbye to it, because.
This is your solution!!
css:
js:
Now you can use —vh as your height value like we would any other vh unit, multiply it by 100 and you have the full height we want.
One thing left, the js up there runs, but we never update the element’s size when the viewport changes, so that wouldn’t work yet, you need a listener.
Источник