Summary: Responsively-scaled sprites sliding and occasionally displaying incorrect sprite.
Background:
I've googled and perused SO for answers to this -- and found a few, such as this one -- but they haven't told me anything I haven't already been over time and time again. I've been working on this over the past week, and I'm feeling extremely frustrated. :(
Problem:
I'm trying to responsively scale chip and card sprites for use in a poker game. I have the scaling working perfectly (and in-game everything repositions and scales perfectly according to table size), but the sprites appear to "slide" during its resizing, and occasionally showing the incorrect card. While endeavoring to discover a solution to this most unseemly behavior, I've encountered numerous sites using scaled sprites correctly, but I cannot for the life of me determine what I'm doing wrong with mine.
Example:
I've prepared a jsfiddle with only the relevant portions displaying the issue, here: http://jsfiddle.net/VsfZD/2/
Applicable CSS: (to satisfy the jsfiddle+code requirement):
/* Cards are 47x64 (spritesheet is 53 cards wide, so 2491x64 px) */
/* Spacer is 47x64 */
.card {
position: absolute;
width: 4%;
max-width: 47px;
z-index: 306;
overflow: hidden;
}
.card img.card_spacer {
display: block;
height: auto;
width: 100%;
}
.card img.card_img {
position: absolute;
top: 0px;
left: 0px;
max-width: none;
max-height: 100%;
}
.two-clubs img.card_img { left: -200%; }
.six-diamonds img.card_img { left: -1600%; }
.ace-diamonds img.card_img { left: -4900%; }
.card_back img.card_img { right: -5200%; }
Please, if you can help me fix this I'll be greatly in your debt!
Additional req's: css only. no frameworks, no bootstrap, no js. must work in IE8
Webkit's penchant for rounding decimals to whole numbers of pixels causes the sliding of sprites. Unfortunately, no amount of css can alter this behavior, rendering my above question impossible.
That said, there is still a way to use scaled sprites within webkit, though by necessity it uses javascript.
As you must ensure that the scaled sprite sizes are always in whole pixels, you should pick a sprite size ratio (such as 3:4) with as frequent (whole-number) multiples as possible, and then only update the displayed sprites' sizes when your scaling results in one of these. It isn't perfectly smooth, and definitely not passive, but it does allow for working, cross-browser scaling.
I've resized our sprites to 66*88, and using this I finally have scaling cards working. At the start of window resizing, javascript hides all of the sprites (cards, chips, etc.) and updates their sizes and locations upon completion. This effectively hides any jittering from the user during resizing, and greatly simplifies animation handling.
Related
I'm trying to position elements in a way so that when the browser width is changed, the webpage will scale everything in proportion, but what happens is that they shift a little. I don't understand why. I can adjust this okay using media queries, but they change drastically in mobile browsers. To illustrate what I'm talking about, I created an example in which I'm trying to keep this black text centered inside this green box. From my example, you'll see that scaling the browser on a desktop will keep the text in the box centered pretty well, but when switching to a mobile browser, the text will go out of the box. What can I do to keep it scaling correctly?
I realize that I can just fill the text div with a green background, but you have to understand that this is just an example of what I'm trying to do. The real webpage is much more sophisticated, so that will not be an option. I need to make sure that these divs scale appropriately. Thank you.
I provided an image to show the problem that I'm getting in my phone browser. It's a bit small, but you can see how the black text dips below the green box.
The example website: http://www.marifysworld.com
CSS:
#viewport {
width: device-width;
zoom: 1.0}
#-ms-viewport {
width: device-width}
body {
margin: 0px;
padding: 0px;
background-color: #fffff}
img {
display: block;
margin: 0px;
padding: 0px}
.text {
font-size: 2.25vw;
color: #000000;
text-align: center;
text-size-adjust: 90%}
.box {
width: 23.75%;
height: auto;
position: absolute;
left: 25%;
top: 40vw}
.divtext {
width: 20%;
height: auto;
position: absolute;
left: 26.75%;
top: 42.5vw}
HTML:
<img class="box" src="http://www.marifysworld.com/images/platform/box.jpg" />
<div class="divtext text">
Why won't this div of text stay in the center of the block in mobile browsers?
</div>
Well, you are using positions for your design but it is confusing and not possible.
Here is an idea to make this design work.
Just try it...
HTML:
<div class="box">
<div class="divtext text">
Why won't this div of text stay in the center of the block in mobile browsers?
</div>
</div>
CSS:
#viewport {
width: device-width;
zoom: 1.0}
#-ms-viewport {
width: device-width}
body {
margin: 0px;
padding: 0px;
background-color: #fffff;
}
.box{
background: url('http://www.marifysworld.com/images/platform/box.jpg');
width: 23.75%;
margin: auto;
margin-top: 20%;
}
.divtext {
width: 90%;
padding: 5% 0;
margin: auto;
}
.text {
font-size: 2.25vw;
color: #000000;
text-align: center;
}
Update: initially I thought the problem might be the (not universally supported) text-size-adjust property, but it seems this is unlikely. I leave those thoughts below just in case they are useful to someone else using that property.
Having been unable to reproduce the problem myself but seeing the useful image now put into the question I think we have to look at the actual font and how it is sized and using space. There are quite a few factors which maybe the browsers are setting different defaults for. Here's a few, there may well be more:
font-family - most obvious but is whichever browser is causing the problem using the same default font as browsers not causing the problem? Try setting a specific font and see what happens
Different fonts will take different widths for different characters. Try a monospace font - that will probably overflow - just to demonstrate the issue
kerning - no I don't fully understand how different fonts use it and what they mean by 'normal' (which is probably the browser's default) but that will also alter the space used as will...
..line height - perhaps that needs to be specifically set
font-weight will alter the space used - do all browsers/systems interpret say 400 exactly the same way
I guess there's loads more that may differ between browsers - for example how exactly do they calculate the spacing needed to center text, will they always break a line at the same place etc.
Sorry this is a waffle, but there are so many factors that could make the text overflow and I don't understand them all in enough depth.
Basically what you need is to be able to scale the text div to force it to fit - for that you would need a bit of JS I think (?or is there an equivalent of contain for divs?)
ORIGINAL STUFF:
I am seeing text stay within the green box on a mobile device (IOS Safari) so I imagine the problem you are having is with another mobile device/browser such as Android.
If this is case the area to look at is the use of the CSS property
text-size-adjust: 90%
There are a couple of things to note here:
According to MDN
This is an experimental technology. Check ... carefully before using in production.
This property is intended to be used in the case where a website has not been designed with smaller devices/viewports in mind.
According to MDN, while Chrome on Android implements text-size-adjust fully, Firefox on Android and Safari on IOS do not support the percentage version.
I may be missing something but the question explicitly states that 'the webpage will scale everything in proportion'. Apart from possible inbuilt browser margin and padding on the div, everything is expressed as vw or % so I cannot see anything else that would have an adverse affect on the text positioning.
I also cannot see why this property is being used. It may or may not be causing the problem, but it certainly may affect how text is displayed on some browsers and it seems to be, at best, redundant for a site that is designed with proportionality in mind from the start.
The incorrect scaled size happens in Webkit browsers, i.e. Chrome, Safari. Chrome version I am using is 68.
Demo: Codepen Link
Code as requested by #Kaiido
HTML:
<div class="test1"></div>
<div class="test2"></div>
CSS:
.test1 {
z-index: 100;
position: fixed;
top: 10px;
left: 10px;
width: 1px;
height: 1px;
background: blue;
transform-origin: top left;
transform: scale(100, 100);
}
.test2 {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: red;
}
In the link above, if you zoom in/out of chrome, you would see the scale size does not necessary match the fixed size of the .test2 div. I would expect the final size of the scale(100, 100) to be exactly the same as the one with width:100px; height: 100px upon scaling but obviously this is not the case.
I have also tested this in both retina mac and pc. It is the same behavior in Chrome. However same code is tested in Firefox and is working correctly.
Is this some sort of bug or am I missing something? Thanks.
It is a bug... caused by the fact these browsers round coordinates to avoid antialiasing.
So when you set your zoom level to 120%, the small square should actually be rendered as a 1.2px*1.2px square prior transform.
But webkit browsers will round this value to 1px, even before they apply the transformation (I think FF also does but probably after transform).
So you won't see a change until you get to zoom 150%, where now it will get rounded to 2px and your blue square will get bigger than the same 100px*100px.
Only at 200% will they match again.
Not much to do to circumvent this, apart letting them know, and avoiding playing with such small elements ;-) (using a 10px*10px square and dividing the transform zoom level by 10 would prevent this bug).
Have caught similar case on mobile Chrome. Scaling 1px value to some width by CSS transform after ~100px result become totally wrong and become worser as continue. In my case this was a js-based range control, where I scale its 'progress' visual part from 1px (base) to current user touchX position by transform: scaleX(touchX);
My vision of problem is based on understanding of CSS units evaluations (https://webplatform.github.io/docs/tutorials/understanding-css-units/): there is sort of eager integer equation for antialiasing on screens with fractional window.devicePixelRatio. Android often has a 2.3, 2.6 DPRs, and it may changes when user changes display's zoom system settings.
My solution involves javascript, so may be inappropriate for you, still may be useful:
fixedWidth = (devicePixelRatio * originalWidth) / Math.round(devicePixelRatio);
I am creating a slider with custom "prev/next" navigation-arrows.
All the animations works fine. I use the transform: scale() to scale up the arrows when hovering and it all works fine. I just have one problem..
I want to prevent the arrow images to scale too.
I think I have tried everything: I've used somekind of :before/:after (see below) and it worked pretty good. But not in Safari (No transition when hover).
http://jsfiddle.net/XF4Qj/5/
Then I tried something else: Putting a span inside the arrow container, and when the arrow container was scaled up, the span was scaled down, but it didn't looked good at all (See below).
http://jsfiddle.net/Ajngc/1/
I have tried for hours, but I cannot get it to work in all major browsers.
So the question is: How to I prevent the arrow-images from scaling too, and just preserve their original dimensions?
It's only the white circle that schould be scaled up, and not the background image.
I've created a third fiddle, which has all the working code from my slider-arrow-functions:
http://jsfiddle.net/Ajngc/2/
Could be really great if someone could help me with this.
Thank you very much
- Jesper
Instead of transform()ing those elements, why not just change the size? See this updated fiddle.
.arrow:hover {
width: 50px;
height: 50px;
top: -5px;
bottom: -5px;
}
.prev:hover {
left: 35px;
}
.next:hover {
right: 35px;
}
I have a div which i want vertically aligned to 50% of the height of the browser window at all times.
I don't know what the height of the browser window is going to be at all times, should the user scale this window. If placing it within another element is necessary, great, but as just specified, I have no idea how tall the viewport is going to be at any one time.
I'm not going to be using javascript either.
I have read through the site, i have gone hunting for a solution, but I really want to throw this out there (again) as I have yet to find a solution that does exactly this, either by hook or by crook.
Thanks.
You don't specify if the has a fixed height or not? If so then you can do this with one element, just add the following example CSS:
.centered {
height: 100px;
width: 100%;
background: red;
position: absolute;
top: 50%;
left: 0;
margin-top: -50px; /* half the height of the element */
}
You could use a number of techniques, depends on how you exactly want to implement it. Some (older) but still relevant reading here.
I need to have a curve-shaped stretchy footer fixed at the bottom of the browser window, where the curve is an image. I've mocked up a live example.
To minimize the loss of "clickable" real-estate in lower layers through the transparent part of the footer image, my instinct is to cut the image into several segments (red boxes in the example) and position them next to each other like so:
#arc-segment-1,
#arc-segment-2 {
position: fixed;
z-index: 2;
bottom: 0px;
}
#arc-segment-1 {
width: 5%; /* where this */
height: 82px;
left: 0;
background-image: url(...);
}
#arc-segment-2 {
width: 5%;
height: 72px;
left: 5%; /* matches this */
background-image: url(...);
}
In most major browsers (not IE and FF), hairline fractures come and go between boxes as the window is resized, which is unacceptable.
Floating the image segments would solve the problem, but I have not found a way of implementing it that still fixes the footer to the bottom and preserve the mentioned "clickability". Is there a better approach to this problem than mine, or can it somehow be remedied?
Note regarding the example given: The curve image itself in the example has not yet been cut, it is still a single image. Also, the blue boxes are not a concern, they will not stretch so they are not affected by the problem.
I'd be interested in both the reasons of this behavior and any workable solution. Thanks.
you can add pointer-events: none; so you can click below
I stumbled over a somewhat workable solution myself while reading at the W3C:
If the width-property of the segments is taken out and both left and right properties are given, say for a 10% wide segment in the middle of the screen:
#arc-segment-3 {
left: 45%;
right: 45%;
}
It will behave like originally intended, although some browsers now seem to overlap the segments with a hairline instead. In my case, this is a much smaller problem as the texture of the arc is weak enough not to be much noticeable. Anyone with a pixel-perfect approach?