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

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 :-)

Related

Styling ion-refresher

I am trying to style the ion-refresher component background on one specific page, because it has a header. It works like expected in Safari, but on the device, it overlays everything on top.
I have tried some stuff with z-index (also with pseudo element) + positioning absolute, but I cannot get the ion-refresher to sit where it normally is. As soon as I add a background-color to the ion-refresher, it will overlay on top.
Any ideas on how to style the background of this element?
The CSS I used. Please note it only overlays everything when I add a background-color.
ion-refresher:global(.ios) {
height: 120px;
ion-refresher-content {
position: relative;
padding-top: 18px;
justify-content: start !important;
&::after {
content: '';
display: block;
width: 100%;
height: 120px;
position: absolute;
top: 0;
z-index: -9999;
background-color: purple;
}
}
:global(.refresher-pulling-icon) {
color: white;
}
ion-spinner {
color: white;
}
}
Any advice on how to debug this?

Keeping Footer At The Bottom Of The Page Without Scrolling

Below is the code that I'm using to create a footer on my website. It looks the way I'd like it to, but have to scroll down to see it on a page that doesn't have much content on it. I'd like it to be at the bottom of the screen without having to scroll down no matter what size the screen may be.
Does anyone know how I can achieve this? How can I get the footer to stay at the bottom of any screen size without have to scroll down to see it?
<html>
<body>
<br><br><footer class="site-footer" style="font-size: 12px;">MORIKOBOSHI©</footer>
<style>
.footer{display: block;
width: 100%;
height: 40px;
text-align: center;
border-top: 1px solid black;
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 10px;}
.page-wrap {
min-height: 100%;
/* equal to footer height */
margin-bottom: -40px;
}
.page-wrap:after {
content: "";
display: block;
}
.site-footer, .page-wrap:after {
/* .push must be the same height as footer */
height: 10px;
}
.site-footer {
text-align: center;
border-top: 1px solid black;
padding: 10px;
}
}
</style>
</body>
</html>

jquery mobile: fixed footer with nav panel not resized, content not centered

view it on jfiddle. (you may need to add the frameworks: jquery 1.11.0, then tick the box for jquery mobile 1.4.4. I tried adding the resources for the versions I use (1.11.1 and 1.4.5 respectively -- but the pages don't render from their link. Sorry 'bout that.)
When I add data-position='fixed' to my footer on a page that has, a reduced width on larger screens (set with a media query in css) and a nav-panel that says open on larger screens using the data-display="reveal" or "push" (no problem with "overlay"), when I open the nav-panel (icon in upper left of header) the footer slides right as it should, but does not resize, and the contents are not centered. The re-sizing toggles if I click on the background, but the content never centers. I've settled on "overlay" as a temporary fix, but I'd prefer to use "reveal" (the default). Much of the CSS for the nav-panel is borrowed from the jquery mobile demos.
To duplicate the problem on the fiddle, use a wide screen and enlarge the output panel so that you see the gradient background, then click on the menu button (bars). After that you can see the footer slide (but not adjust its width) and slide back to an adjusted width (but not center the icons in the footer).
Any ideas what I did wrong or what CSS might resolve the issue?
Here's the html:
<body>
<div data-role="page" id="index-page" class="ui-responsive-panel" data-title="MMT" data-url="index-page" data-theme="a">
<div data-role="header" >
<h6 class='header' style="overflow:visible !important;">Test Page</h6>
Contact
</div><!-- /header -->
<div data-role="panel" class="jqm-navmenu-panel" data-position-fixed="true" data-display="reveal" id="index_nav-panel">
<ul data-role="listview">
<li>Close Menu</li>
<li>Blah</li>
<li>Foo</li>
<li>Bar</li>
<li>Bat</li>
</ul>
</div>
<div role="main" class="ui-content"><div class="banner">Banner Image </div>
<p>text</p>
<div style='margin-top:44px;'>
<ul data-role="listview">
<li>Foo</li>
<li>Bar</li>
<li>Bat</li>
<li>Baz</li>
<li>Biz </li>
</ul>
</div>
<div data-role='collapsible' class='ui-nodisc-icon' data-collapsed-icon="home" data-expanded-icon="carat-u" data-mini='true'>
<h3>Follow...</h3>
<p>Follow us on Twitter:</p>
</div>
</div>
<div data-role='footer' data-position='fixed'>
<div class='footer'>
Contact Phone:
Twitter
</div>
</div><!-- /footer -->
here's the css
/*css file for mobile website*/
#media all and (max-width: 50em) {
.my-breakpoint .ui-block-a,
.my-breakpoint .ui-block-b,
.my-breakpoint .ui-block-c,
.my-breakpoint .ui-block-d,
.my-breakpoint .ui-block-e {
width: 100%;
float:none;
}
}
.banner img{
display:block;
width: 100%;
height: auto;
margin-left: auto;
margin-right: auto
}
/* set a width for wide screens */
.collapsible {
max-width:900px;
}
/* to center the content on wide screen pc or laptop */
#media only screen and (min-width: 1025px){
.ui-page{
width: 960px !important;
margin: 0 auto !important;
position: relative !important;
/*border-right: 3px rgb(93, 105, 105) outset !important;
border-left: 3px rgb(93, 105, 105) outset !important;*/
}
.ui-footer {
max-width: 960px !important;
margin: 0 auto !important;
}
}
.header, .firm {font-family: 'IM Fell French Canon SC', serif !important;}
.firm{font-size:1.2em; font-weight:bold;}
.ui-header .ui-title {
margin-right: 10%;
margin-left: 10%;
}
/*panel background color*/
div#index_nav-panel{
background-color: rgba(91, 95, 97, 0.1) !important;
}
/*panel stays open on desktops*/
#media (min-width:35em) {
/* wrap on wide viewports once open */
.ui-panel-page-content-open.ui-panel-page-content-position-left {
margin-right: 17em;
}
.ui-panel-page-content-open.ui-panel-page-content-position-right {
margin-left: 17em;
}
.ui-panel-page-content-open {
width: auto;
}
/* disable "dismiss" on wide viewports */
.ui-panel-dismiss {
display: none;
}
/* same as the above but for panels with display mode "push" only */
.ui-panel-page-content-open.ui-panel-page-content-position-left.ui-panel- page-content-display-push {
margin-right: 17em;
}
.ui-panel-page-content-open.ui-panel-page-content-position-right.ui-panel- page-content-display-push {
margin-left: 17em;
}
.ui-panel-page-content-open.ui-panel-page-content-display-push {
width: auto;
}
.ui-panel-dismiss-display-push {
display: none;
}
div.footer {
text-align: center;
letter-spacing: .2em;
font-size: 1em;
}
}
/* #### target mobile devices with max device width 480px #### */
#media screen and (max-device-width: 480px){
div.footer {
font-size: .75em;
}
div.footer a.ui-btn {
margin-top: 0.1em !important;
}
}
div.footer {
text-align: center;
/* font-size: .75em;
*/}
.footer-text{
color: #999;
margin-left:-8px;
}
/*popup dialog background color*/
div#popupSocialMedia, div#popupDialog {
background-color: rgb(237,237,237);
}
div#popupDialog .ui-content {
height: 50%;
}
div.ui-content { background-color: #f9f9f9 !important;}
.ui-overlay-a, .ui-page-theme-a, .ui-page-theme-a {
background-color: rgb(10, 10, 10) !important;
background: #d2b48c; /* old browsers */
background: -webkit-linear-gradient(#efefef,#000000) fixed; /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(#efefef,#000000) fixed; /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
}
#media (min-width: 60em) {
.jqm-demos .jqm-header h2 {
padding: 1em 0 .7em;
margin: 0 1em 0 3%;
text-align: left;
}
.jqm-demos .jqm-header h2 img {
width: 275px;
height: 78px;
}
.jqm-demos .jqm-header p {
bottom: auto;
left: auto;
top: 50%;
right: 15%;
font-size: 1.2em;
margin-top: -.625em;
}
.jqm-demos .jqm-navmenu-link {
display: none;
}
.jqm-demos .jqm-search-link {
right: 3%;
}
.jqm-demos .jqm-footer p {
float: right;
margin: 1.5em 3% 1.5em 1.5em;
}
.jqm-demos .jqm-footer p:first-child {
float: left;
margin: 1.25em 1.25em 1.25em 3%;
}
.jqm-demos .jqm-navmenu-panel {
visibility: visible;
position: relative;
left: 0;
clip: initial;
float: left;
width: 25%;
background: none;
-webkit-transition: none !important;
-moz-transition: none !important;
transition: none !important;
-webkit-transform: none !important;
-moz-transform: none !important;
transform: none !important;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.jqm-navmenu-panel .ui-panel-inner {
margin-top: 3em;
margin-bottom: 3em;
}
.jqm-navmenu-panel .ui-listview .ui-btn {
padding-left: 12.5%;
text-shadow: none !important;
}
.jqm-navmenu-panel .ui-listview .ui-listview .ui-btn {
padding-left: 15%;
}
.jqm-navmenu-panel .ui-collapsible,
.jqm-navmenu-panel .ui-collapsible-content,
.jqm-navmenu-panel .ui-btn {
background: none !important;
border-color: #ddd !important;
}
.jqm-navmenu-panel .ui-btn.ui-btn-active {
color: #3388cc !important;
}
.jqm-navmenu-panel .ui-btn::after {
opacity: 0;
-webkit-transition: opacity 500ms ease;
-moz-transition: opacity 500ms ease;
transition: opacity 500ms ease;
}
.jqm-navmenu-panel .ui-btn:hover::after {
opacity: .6;
}
.ui-panel-dismiss-open.ui-panel-dismiss-position-right {
left: -17em;
right: 17em;
}
}
I've omitted the javascript... from here and the fiddle.
Thanks for looking at this...
screenshot of the footer extended
...screen shot of the footer retracted after clicking on the background
The problem goes away if I remove "data-position="fixed" from the footer.
Posting my own answer at #twisty's suggestion. See his comments, too.
It turns out that since I found a different stackoverflow solution to keep my pages full size, my display is the same without data-position="fixed"... so I just removed it and all works as it "should". I'm curious to know why the footer doesn't work the same as the header, but don't want to spin anyone's wheels since I can now move forward without the issue
In case anyone wants to know where my 'fix' was, it's thanks to #ezanker, whose jfiddle shows the code: jsfiddle.net/zKS76/19 and Omar, whose answer to the op's question on so is stackoverflow.com/questions/21552308/…;.
#twisty suggests the reason that headers and footers behave differently: " When it is "fixed" it's removed from that wrapper and has a z-index of 1000, and is sort of stand alone from the rest of the page. "

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

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

Is it possible to create a cool transition/animation the eBay tablet app uses with regular HTML/CSS?

For those of you who have ever used the eBay app on a tablet device, you may have noticed that when you touch a product, the product view switches from a standard grid view like the following:
To a view like the following where all the products are moved to a left nav and the details about the touched product are put in the right area:
The thing that's really cool is the animation that transforms the view from one to the other.
Specifically, the product images shrink down a bit and then slide over to wherever they belong in the left nav. (This is much easier to see with the actual app than for me to explain.)
Anyway, I really like the animation, and I'd love to be able to create the same effect on a website using HTML/CSS, but I've had no luck.
I tried placing a bunch of divs next to each other on the screen and (with the click of a button) using CSS3 transitions to shrink the width of the containing div, but all that resulted in was the divs making a sudden jump from one location to another without any sort of fluid animation or movement, which I would ideally like.
If what I'm looking to achieve is impossible with just HTML/CSS, then that's fine, but I'd like to defer the question to those much wiser than me before I give you.
If anyone knows how to do this (or can conclusively tell me that it's impossible), I'd be very appreciative.
Thank you.
It is not difficult, just a little boring to do all the details
for this html
<div class="container">
<div id="elem1"></div>
<div id="elem2"></div>
<div id="elem3"></div>
<div id="elem4"></div>
<div id="elem5"></div>
<div id="elem6"></div>
<div id="elem7"></div>
<div id="elem8"></div>
<div id="elem9"></div>
</div>
I have prepared this CSS
.container {
position: relative;
width: 300px;
height: 300px;
border: 1px solid green;
}
.container div {
position: absolute;
width: 100px;
height: 100px;
border: 1px solid red;
background-color: lavender;
}
#elem5 {
left: 100px;
top: 100px;
}
.container:hover div {
-webkit-animation-duration: 3s;
-webkit-animation-direction: normal;
-webkit-animation-fill-mode: forwards;
}
#elem5 {
left: 100px;
top: 100px;
}
.container:hover #elem5 {
-webkit-animation-name: an5;
}
#-webkit-keyframes an5 {
0% {-webkit-transform: scale(1);}
50% {-webkit-transform: scale(0.33);}
100% {-webkit-transform: translateX(-133px) scale(0.33);}
}
#elem9 {
left: 200px;
top: 200px;
}
.container:hover #elem9 {
-webkit-animation-name: an9;
}
#-webkit-keyframes an9 {
0% {-webkit-transform: scale(1);}
50% {-webkit-transform: scale(0.33);}
100% {-webkit-transform: translateX(-233px) translateY(33px) scale(0.33);}
}
I have set an array of 9 elements, that would fit an 3x3 grid.
And I have positioned the 5th and 9th of them where they should be, and created an animation to move them to the list position.
(Only webkit transforms)
There is left to create animations for the other 7 elements, and to elaborate the animations (with more keyframes)
jfiddle
As per your comment, an alternate way to do it.
The demo is prepared for a grid of 3 columns. Then, the key is to have only the first child of every 3 in flow; the remaining 2 are out of flow since they are positioned absolute. This allows us to create generic rules based in nth-child for the positioning of the elements.
Once you have the animations set, this style adapts to any number of elements (and you have only to set as many animations as columns has your design)
CSS
.container {
height: 500px;
}
.child {
width: 100px;
height: 100px;
font-size: 40px;
text-align: center;
line-height: 90px;
box-shadow: inset 0px 0px 2px black;
}
.child:nth-child(3n+1) {
background-color: lightblue;
}
.child:nth-child(3n+2) {
position: absolute;
-webkit-transform: translate3d(100px, -100px, 0px);
background-color: lightgreen;
}
.child:nth-child(3n) {
position: absolute;
-webkit-transform: translate3d(200px, -100px, 0px);
background-color: lightyellow;
}
.container:hover .child {
-webkit-animation-fill-mode: forwards;
-webkit-animation-duration: 8s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: linear;
width: 300px;
}
.container:hover .child:nth-child(3n+1) {
-webkit-animation-name: ani1;
}
.container:hover .child:nth-child(3n+2) {
-webkit-animation-name: ani2;
}
.container:hover .child:nth-child(3n+3) {
-webkit-animation-name: ani3;
}
#-webkit-keyframes ani1 {
0% {width: 100px; -webkit-transform: scale(1);}
50% {width: 300px; -webkit-transform: translate3d(-70px, -20px, 0px) scale(0.33);}
100% {width: 300px; -webkit-transform: translate3d(-100px, -40px, 0px) scale(0.33);}
}
#-webkit-keyframes ani2 {
0% {width: 100px;-webkit-transform: translate3d(100px, -100px, 0px) scale(1);}
50% {width: 300px; -webkit-transform: translate3d(0px, -90px, 0px) scale(0.33);}
100% {width: 300px; -webkit-transform: translate3d(-100px, -106px, 0px) scale(0.33);}
}
#-webkit-keyframes ani3 {
0% {width: 100px; -webkit-transform: translate3d(200px, -100px, 0px) scale(1);}
50% {width: 300px; -webkit-transform: translate3d(80px, -100px, 0px) scale(0.33) rotate(180deg);}
100% {width: 300px; -webkit-transform: translate3d(-100px, -73px, 0px) scale(0.33) rotate(359.99deg);}
}
Reusable fiddle
(Only for webkit. Just for fun, added some rotation)
On an iPad you can do this with the CSS -webkit-transform property.
CSS
.menu-open {
-webkit-transform: translate3d(260px, 0, 0);
}
#main {
-webkit-transition: -webkit-transform 150ms ease-in;
transition: -webkit-transform 150ms ease-in;
overflow: visible;
width: 100%;
margin: 0;
padding: 0;
outline: 0;
border: 0;
top: 0;
left: 0;
position: absolute;
color: #333;
background-color: white;
display: block;
min-height: 100%;
}
#menu
{
position: absolute;
width: 100%;
position: absolute;
width: 259px;
top: 0;
left: 0;
background: white;
margin: auto;
min-height: 100%;
height:auto !important;
height:100%;
overflow: hidden !important;
display:block;
}
HTML
<div id="menu" style="display:none; background-color: #cccccc;">
<div>Text</div>
</div>
<div id="main">
<input type="button" id="menuToggle" value="Toggle" />
</div>
JS
function showMenu() {
$("#menu").show(0);
$("#main").addClass('menu-open');
}
function hideMenu() {
if ($("#main").hasClass('menu-open')) {
$("#main").removeClass('menu-open');
setTimeout(function () { $("#menu").hide(); }, 500);
}
}
$(document).ready(function () {
var body = $("#main"),
menuToggle = $('#menuToggle'),
menu = $("#menu");
menuToggle.bind('click', function (ev) {
ev.preventDefault();
if (body.hasClass('menu-open')) {
hideMenu();
} else {
showMenu();
}
});
});
See this JsFiddle for an example. Hope I understood you correctly (no iPad here at the moment).

Resources