Overflow-scrolling:touch breaks overflow:hidden on child elements in Mobile Safari - ios

I am trying to draw a half circle and rotate it using CSS. Like so;
To style the div.circle I use border-radius:50%; then I wrap it in an overflow:hidden; div.mask that is half the width of the circle, thus hiding half of the circle. Then I use transform:rotate(45deg) to rotate the div.mask. This works fine in all browsers that I've tested.
<div class="mask">
<div class="circle"></div>
</div>
.mask {
outline: 1em solid red;
overflow: hidden;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
}
.circle {
-webkit-border-radius: 50%;
border-radius: 50%;
background: blue;
width: 200%;
height: 100%;
}
But when I place this element in a block that has overflow-scrolling:touch; and overflow:scroll; and view it on Mobile Safari on iOS7 the half circle becomes a full circle because the overflow:hidden; on the div.mask doesn't seem to have an effect anymore.
.scroller {
border: 1em solid green;
overflow: scroll;
-webkit-overflow-scrolling: touch;
overflow-scrolling: touch;
}
How do I fix this?
Here's a live example

Related

Is there anything I can do to remove the 1px border appearing around this SoundCloud widget?

As you can see
, there is a 1px border around the widget. It only appears on iOS. I can see the CSS that's causing this in the inspector:
.widget {
...
border: 1px solid #e5e5e5;
...
}
This is the iframe:
<iframe src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/307068209&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&visual=true" scrolling="0" frameborder="0"></iframe>
I know CSS can't effect elements coming from a different domain in an iframe, but client says it looks bad. Is there something that I might be doing to cause this to appear? If not, is there a way I can remove this?
You could hide/clip the outermost 1px of the entire iframe, but that may or may not have a desirable effect. http://codepen.io/anon/pen/evKLMr
div {
overflow: hidden;
width:398px;
height:198px;
}
iframe {
position: relative;
top:-1px;
left:-1px;
width: 400px;
height: 200px;
}
I ended up taking advice from this post:
CSS: Inset shadow by parenting div over iframe
And added this bad boy:
.iframe-wrapper:before{
position: absolute;
content: '';
top: 0;
left: 0;
box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, .4) inset;
z-index: 1;
width: 100%;
height: 100%;
}
Which hides the border well enough
It should be
frameborder="no"
rather than
frameborder="0"

IOS Phonegap : landscape to portrait break overflow-x

I've got an issue and can't solve it easily because appears only in one case : when i'm on my page and i switch from landscape to portrait, on iOS.
My app is a Phonegap app using Angular and plugin device-orientation to make it working with my responsive CSS.
All is fine, except this part.
I've got an horizontal menu and i wan't user able to scroll it if there is overflow.
Here is my code :
CSS
nav.inline {
background: #e4eeef;
outline: 1px solid #e4eeef; /* Safari bug rendering */
overflow: hidden;
overflow-x: scroll;
text-transform: uppercase;
-webkit-overflow-scrolling: touch;
}
nav.inline ul {
list-style: none;
min-width: 102%;
padding: 0 2%;
width: 102%;
white-space: nowrap;
}
nav.inline ul li {
display: inline-block;
white-space: nowrap;
}
nav.inline ul a {
border-bottom: 4px solid transparent;
border-top: 4px solid transparent;
color: #4b8c95;
display: inline-block;
font-size: 1.7em;
font-weight: bold;
line-height: 80px;
margin: 0 0.7em;
}
nav.inline ul a.active {
border-bottom: 4px solid #4b8c95;
}
HTML
<nav class="fullwidth inline" ng-include="'partials/nav.html'"></nav>
And the partial associated
<ul data-snap-ignore="true">
<li><a ng-click="setTab('link1')">Link 1</a></li>
<li><a ng-click="setTab('link2')">Link 2</a></li>
...
</ul>
You can see "data-snap-ignore" because i'm using angular-snap.js for an other menu (left menu) and i don't wan't him to appear when i'm sliding this one (this part is working well).
Thanks for helping ;)
Yep, this sucks. It's a bug, AFAICT.
So far the only mechanism I've found to fix it is to toggle display from none to block on the container, like so:
var navElement = document.getElementsByTagName("nav")[0];
navElement.style.display = "none";
setTimeout ( function() { navElement.style.display = "block"; }, 0 );
Which *looks * horrible, in my opinion, but it does restore the scrolling ability.
Since, as far as I can tell, it never breaks if the elements within force the container to scroll, it should work to ensure that the container always scrolls, even if by a pixel or two.

iOS Web View with Blurry Text

I have a web-view with blurry text in iOS 7. There are many posts with solutions, however none of them seem to work in my case. The best solution that I've found thus far is to apply -webkit-transform: translateZ(0); to the blurry elements, as seen here. But doing this causes -webkit-overflow-scrolling: touch; to become inoperable. Any advice would be much appreciated.
UPDATE: Here is the CSS associated with the scrolling wrapper and elements containing blurry text
#scrolling_element {
position: relative;
height: 100%;
width: 100%;
overflow: hidden;
-webkit-overflow-scrolling: touch;
overflow: auto !important;
}
.elements_w_blurry_text {
position: relative;
border: 1px solid #000;
background-image: url("../path/to/img.png");
background-repeat: repeat;
-webkit-transform: translateZ(0);/* or any other suggested code*/
}
Try adding this into your css:
-webkit-text-size-adjust:none;

How to make one side of a div pointy with CSS?

I'm trying to create a pointy button like this:
So far, I was only able to achieve this:
I thought increasing the horizontal border-radius would make it sharp, but all it does it make the roundness longer.
HTML
<a class="button">Back</a>
CSS
.button {
display: inline-block;
height: 3em;
padding: 0 0.7em 0 1.4em;
border: 0.1em solid black;
border-radius: 3em 0.4em 0.4em 3em / 1.5em 0.4em 0.4em 1.5em;
background: -moz-linear-gradient(
top,
#fff,
#ccc
);
}
You don't want to be using border-radius as that assigns a quarter-circle shape to each specified corner. Instead you hack it with specific border-width properties, as illustrated in this site: http://www.howtocreate.co.uk/tutorials/css/slopes
However I feel you're solving the problem the wrong way; what you're doing is best done using a background image, which is how the iOS-style Back buttons are implemented in iPhone-for-web stylesheets. If you need something resolution-independent then you can use SVG without penalty now.
Having thought about it more, this is a more elegant solution that allows much more effective styling and the use of just one HTML element. Using this method, we can achieve the results in your concept completely.
HTML
Back
CSS
a.button {
text-decoration:none;
color:#111;
text-shadow:0 1px 0 #fff;
font-weight:bold;
padding:10px 10px;
font-size:14px;
border-radius:0 8px 8px 0;
-webkit-border-radius:0 8px 8px 0;
float:left;
margin-left:30px;
margin-top:20px;
position:relative;
font-family:verdana;
color:#3b3d3c;
border:1px solid #666;
border-left:0;
background: -moz-linear-gradient( top , #eee 0%,#bbb 100%);
background: -webkit-linear-gradient( top , #eee 0%,#bbb 100%);
}
a.button:after {
content:"";
width:25px;
height:25px;
background: -moz-linear-gradient( left top , #eee 0%,#bbb 100%);
background: -webkit-linear-gradient( left top , #eee 0%,#bbb 100%);
-moz-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
display:block;
position:absolute;
top:5px;
left:-14px;
z-index:-1;
border:1px solid #666;
}
#media screen and (-webkit-min-device-pixel-ratio:0) {
a.button:after{
border-left:0;
left:-13px;
}
The last rule is for Chrome, which otherwise renders the result slightly differently.
Hope this helps.
You can create such an effect using 2 elements side by side wrapped in the anchor tags.
<style type="text/css">
.arrow-left {
width:0;
height:0;
border-top:30px solid transparent;
border-bottom:30px solid transparent;
border-right:30px solid orange;
float:left;
}
.button {
float:left;
height:60px;
background:orange;
width:50px;
line-height:60px;
font-weight:bold;
border-top-right-radius:8px;
border-bottom-right-radius:8px;
}
</style>
</div><div class="button">Back</div>
I'm not sure if it's the most refined solution, but it certainly looks the same as your concept art and functions as intended.

Moving the arrow from the bottom to the left side of the tooltip in the tooltip widget (jQuery UI 1.9)

I'm using a speech bubble style tooltip based on the jquery ui tooltip widget 'Custom Styling' demo, but I'm having trouble properly displaying the arrow when I need it on the left side of the tooltip instead of on the top or bottom.
Can someone help me fix this code (it cuts off the tip and displays too large a section of the arrow)?
<style type="text/css">
.ui-tooltip.menu_info {
max-width: 200px;
}
* html .ui-tooltip {
background-image: none;
}
body .ui-tooltip { border-width: 1px; }
.ui-tooltip, .arrow:after, .arrow_left_side:after {
background: white;
border: 1px solid #999;
}
.ui-tooltip {
padding: 10px 12px;
color: Black;
font: 8pt "Helvetica Neue", Sans-Serif;
max-width: 150px;
border: 1px solid #999;
position: absolute;
}
.arrow_left_side {
height: 70px;
width: 8px;
overflow: hidden;
position: absolute;
top: 0px;
margin-top: 5px;
left: -8px;
}
.arrow_left_side:after {
content: "";
position: absolute;
width: 25px; height: 25px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
tranform: rotate(45deg);
}
</style>
<script>
$(function() {
$('.menu_info').tooltip({
position: {
my: "left+20 center",
at: "right center",
using: function (position, feedback) {
$(this).css(position);
$("<div>")
.addClass("arrow_left_side")
.addClass(feedback.vertical)
.addClass(feedback.horizontal)
.appendTo(this);
}
}
});
});
</script>
Problem Description
The problem is caused by a combination of the CSS transformation and the overflow:hidden. The arrow is actually a square with width and height that is rotated 45o. The default origin point for the rotation is 50% 50% or center center which results in the "arrow" square being rotated around the middle which results in the edges being clipped by the overflow property.
It's best shown as an image or a demo (Webkit only), but the code used to demonstrate the problem is also below.
The 1st box shows the starting position of the "arrow" square, the 2nd box shows a small rotation around the center point. You can see that the edge is clipped already by the containing block's overflow:hidden. The 3rd shows a 45o rotation which demonstrates the problem you have. The 4th adds CSS to move the origin point to 0 25px, that is x=0, y=25px which is the bottom left corner, so you can see a small rotation around this point is looking better. The 5th pane shows a full 45o rotation around the modified origin. This looks much better and all that is left to do is reduce the width of the container to clip off the right hand side which leaves a left facing arrow. Then some simple CSS positioning to move it into place next to the tooltip content.
Solution
The modification needed to your CSS are small positioning changes on the container and the addition of an origin point for the rotation. I realise in the above description that I said an origin of 0 25px but in practice the arrow was still being clipped on the left side so I moved the origin out to 5px 25px instead.
.arrow_left_side {
margin-top: -5px;
left: -10px;
}
.arrow_left_side:after {
-webkit-transform-origin: 5px 25px;
/* for brevity, I have not added all the different browser prefix versions of transform-origin. If you need cross browser support, you will need to add these here */
}
See demo of the above changes
Demo Code
For completeness, here is the code to generate the above image. It's useful to interact with the demo by changing the rotation in the Chrome DevTools to see the square rotating in real time.
HTML
<div class="original"></div>
<div class="original-rotated-a-little"></div>
<div class="original-rotated-forty-five"></div>
<div class="original-with-transform-origin-rotated-a-little"></div>
<div class="original-with-transform-origin-rotated-forty-five"></div>
CSS
body {
margin-left:50px
}
div {
position:relative;
height: 50px;
width: 35px;
overflow: hidden;
top: 0px;
margin-top: 5px;
left: -8px;
border:1px dashed red;
}
div:after {
content: "";
position: absolute;
border: 1px solid #999;
width: 25px;
height: 25px;
}
div.original-rotated-a-little:after {
-webkit-transform: rotate(15deg);
}
div.original-rotated-forty-five:after {
-webkit-transform: rotate(45deg);
}
div.original-with-transform-origin-rotated-a-little:after {
-webkit-transform-origin: 5px 25px;
-webkit-transform: rotate(15deg);
}
div.original-with-transform-origin-rotated-forty-five:after {
-webkit-transform-origin: 5px 25px;
-webkit-transform: rotate(45deg);
}
Hope this helps :-)

Resources