I am using flot.js for charts with timestamp on the x-axis. As I will have quite a lot of ticks on these charts I am rotating them vertically so they do not overlap. This works fine, but the labels are centered on the tick and there is not enough room provided so they are cutoff.
I am NOT using the tickrotor plugin at tickrotor. I tried it and there were more problems than benefits. Instead I am using plain css which I found here on SO via rotate tick labels, however, in the post it appears they are not having the problem I am (perhaps there was some missing information there?).
Furthermore, I need to support IE8. The post mentioned above talks about using filter or -ms-filter, but fails to mention the css to accomplish that.
I was under the impression that even with the tick rotation it would correct the height accordingly, but that doesn't seem to the case. I also checked out flot's github and while they mention working on this feature it has still not been implemented.
I know a lot of people have the need to rotate the ticks, but I have not found anything which resembles my issue (centered and cutoff).
Any help or ideas would be appreciated.
#flot_chart div.xAxis div.tickLabel
{
transform: rotate(-90deg);
-ms-transform:rotate(-90deg); /* IE 9 */
-moz-transform:rotate(-90deg); /* Firefox */
-webkit-transform:rotate(-90deg); /* Safari and Chrome */
-o-transform:rotate(-90deg); /* Opera */
/*rotation-point:50% 50%;*/ /* CSS3 */
/*rotation:270deg;*/ /* CSS3 */
}
You are going to have lots of problems rotating the labels yourself. This is why the flot-tickrotor exists after all.
Flot sizes it's canvas within the placeholder div to leave enough room for the labels. By rotating them through CSS you are 1.) rotating around the center of the div (hence they go into the canvas area - hint you'll need to shift them down) and 2.) you are overflowing the div container (hint - you'll need to exapand the parent placeholder div). The example you link to works because the text is wrapped and about the same size rotated or not rotated.
Now, the flot-tickrotor deals with these by hooking the low level code of flot and resizing the canvas to make room for the rotated labels (it also gets rid of the label divs and draws the labels using the canvas - which helps with old IE).
So if you really want to pursue rotating the labels yourself, study the code to the plugin and have fun recreating it's functionality.
EDITS
Here's an attempt to use your CSS and make some on the fly adjustments so things will fit:
// push the labels down half their width
// while we are at it find longest label height
var longest = -1;
$('#flot_chart .xAxis .tickLabel').each(function(){
var self = $(this);
var width = self.width();
self.css('top',parseInt(self.css('top')) + width/2 - 5);
if (width > longest){
longest = width;
}
});
// now adjust the chart height so we don't overflow
$("#flot_chart").height($("#flot_chart").height() + longest - $('#flot_chart .xAxis .tickLabel').height() + 5);
See fiddle demonstration here.
Give Padding Bottom and position relative to your main container.
And, give position absolute to your labels and give bottom 0px.
like,
.main-container { padding-bottom:50px; position:relative; }
and
#flot_chart div.xAxis div.tickLabel
{
position:absolute;
bottom:0px;
transform: rotate(-90deg);
-ms-transform:rotate(-90deg); /* IE 9 */
-moz-transform:rotate(-90deg); /* Firefox */
-webkit-transform:rotate(-90deg); /* Safari and Chrome */
-o-transform:rotate(-90deg); /* Opera */
/*rotation-point:50% 50%;*/ /* CSS3 */
/*rotation:270deg;*/ /* CSS3 */
}
I hope this will solve your issue.
If not, than please show your full code via Jsfiddle.
This is a very old question still posting my experience.
I too faced the same issue so I started a trial and error and found that if the max-width is set to a lower value it works fine.
Below is the css that fixed the issue for me (in addition to the the one mentioned in the question).
300 is the max height of the graph I am using,
the max width being set earlier was 71px
#flot-placeholder div.xAxis div.tickLabel {
max-width : 30px !important;
top: 300px !important;
}
Related
URL: https://www.royalsmushicafe.dk/
I have issues with the left side menu text looking blurry on mouseover. It's as if it's blurry during the animation and turns crisp again only after the animation is over. In Safari it stays blurry.
I'm using Transform: scale(1.2) and -webkit-font-smoothing: subpixel-antialiased;, but have tried quite a lot of suggested solutions.
I've been browsing StackOverflow and Google without luck, with suggestions like using transform perspective(1px), scale3d, translate3d( 0, 0, 0), backface-visibility: hidden even filter: blur(0) and whatnot – nothing has resulted in the expected behaviour of a crisp text scaling on mouseover :(
Any help would be much appreciated
I've just had almost the exact same problem, and found all the same hack ideas for perspective(1px), backface-visibility: hidden, and so on, with no success. Chrome and Firefox are fine, but scaled-up text blurs horribly in Safari. For anyone else experiencing this, the band-aid solution is to scale down instead of up.
In my case, I have a label that moves and changes scale when the input has content:
label {
will-change: transform, color;
transform: translate3d(0,0,0);
transform-origin: top left;
height: 20px;
}
input:placeholder-shown:not(:focus) + label {
transform: translate3d(0,.6rem,0) scale3d(1.5,1.5,1);
}
Idea here is that the label has the same styles if the input is focused or has content, and is bigger if the input is empty and unfocused (hence the funky pseudoclass selector.)
The problem is that using transform like this triggers GPU compositing on the <label>. When this happens, the composited layer is rendered like a bitmap in the GPU, at the dimensions calculated during CSS layout (20px here). Then, the GPU layer is scaled up (in this case by 1.5x, so it's now 30px high, and blurry).
Chrome and Firefox seem to re-render the layer at final scale which un-blurs it. Safari does not, probably to save memory since the composited layer is dimensionally smaller (20px high instead of 30px).
To make it work better, I opted to scale down:
label {
will-change: transform, color;
/* reverse the scaling ratio */
transform: translate3d(0,0,0) scale3d(0.67, 0.67, 1);
transform-origin: top left;
height: 20px;
}
input:placeholder-shown:not(:focus) + label {
/* reset to scale of 1 */
transform: translate3d(0,.6rem,0) scale3d(1,1,1);
}
The scaled-down text is a tiny bit blurry, but much less noticeably. I might try different -webkit-font-smoothing values, although I don't hold out a lot of hope because of the way GPU rendering works. Scaling ratios that resolve to a clean, integer pixel font size will probably work better, too.
Would backface-visibility: hidden; help? I recall having similar problems and it did help.
As you know, the <canvas> element in HTML5 has an internal size, set via elm.width and elm.height where elm is the DOM element.
The element within the DOM itself can have a different box size, set via CSS.
When the two differ, the browser automatically stretches the contents of the <canvas> to fit the content box size. Can this behaviour be adjusted without an extra element? Can it be set to something like background-size: contain so that it keeps the aspect ratio of the inner canvas size?
As far as I know, there is no standard way to do this, so webkit-specific hacks are also accepted. But if there is no way to do it at all, what's the most elegant to do it with a wrapper element (we all know that we can wrap the element and adjust it via JS on resize)?
The one solution I can think of is actually using background-size: contain and background: element() but this is Firefox-specific, and I am looking for a WebKit solution.
Side question, can a difference in element box and canvas internal sizes impact performance? If so, how much?
Yes, there is a new CSS property called object-fit. This allow you to set the content to for example cover which will then force aspect ratio to be kept at the same time as filling the DOM box.
Simply add this rule to the canvas element:
canvas {
object-fit: cover;
}
Support
(Updated) It is (partially) supported in Safari, but not in IE. Opera Mini needs a -o- prefix.
Does not seem to work with WebGL canvas (or video) in Chrome likely related to these issues: issue #1, issue #2, issue #3.
As a fallback the size can be calculated manually. This can be used with drawImage. If drawImage is not an option it will require a wrapper element with overflow set to hidden to work.
Example
Both canvas' below are using the default bitmap size of 300x150. They are then stretched by defining CSS size 300x300 pixels.
Normally this would make the circle an oval. However, the canvas on the right will use the new object-fit rule set to cover, the bitmap will be scaled considering aspect ratio so we still get a circle, but of course we'll also loose some of the edges (as well as sharpness).
var ctx1 = document.getElementById("c1").getContext("2d");
var ctx2 = document.getElementById("c2").getContext("2d");
drawCircle(ctx1, 150, 75, 70); // draw circle to stretched canvas 1
drawCircle(ctx2, 150, 75, 70); // draw circle to object-fit/cover canvas 2
function drawCircle(ctx, x, y, r) {
ctx.moveTo(x + r, y);
ctx.arc(x, y, 70, 0 , 6.28);
ctx.closePath();
ctx.stroke();
}
#c1, #c2 {
width:300px;
height:300px;
}
#c2 {
-o-object-fit: cover; /* for Opera Mini */
object-fit: cover; /* W3C version (incl. FF/webkit) */
}
<canvas id="c1"></canvas><canvas id="c2"></canvas>
I've got two inputs, styled primarily by Zurb's Foundation framework. They're in a .row.collapse and each in a .medium-6.columns (these columns are 50% width, floated left, no margins). The inputs themselves are 100% wide within their containers. It's all pretty simple, and the Inspector and jQuery.css are all returning what I'd expect them to. But there's a border issue. Here's the gist of the CSS:
input {
border: 1px solid #dddddd;
&.first {
border-right-width: 0;
}
}
This is to have the effect of collapsing the middle border. But for some reason, this border-right-width: 0 is throwing Webkit (Chrome and Safari but not Firefox) off. The inspector shows 1px border, and the proper border-color. The white input background lines up properly with the second input (that is, there's room for the border), but there's no gray border. Maybe it's rendering transparent?
If I open this up on a retina display, it renders normally - proper borders on both. If I zoom in, the borders show up when it hits the "small" media query (mobile device sizes). But I can't make this border show up on a non-retina, desktop display in Chrome.
Here's how it looks in Chrome:
And here's how it looks in Firefox:
To double-check, I used the Web Inspector to apply a simple border to the first element. It showed up fine (looked like the Firefox screenshot). Adding border-right-width: 0 reintroduced the problem. It seems clear that that's the issue. But I don't know why?
It seems like border-radius may play into this as well? The Firefox screenshot above shows a double-border in the middle, despite the Inspector showing 0 right border. If I uncheck border-radius, in Firefox, it fixes that issue.
These properties should all be independent of one another. Why are they affecting each other?
Edit
Trying to recreate in codepen. Unsuccessful so far, but it looks like it has something to do with transform - these inputs are in a container that is set with the following
position: absolute;
top: 50%;
left: 50%;
#include transform(translate(-50%,-50%));
This has the effect of vertically and horizontally centering the element no matter the width or height in modern browsers. When I turn off transform the border shows up as it should. As I understand, transform accesses the GPU? Or it can? It seems quite possible that this is what's throwing it off. If you look at the screenshot, there are strange border artifacts (like, a partial, interior border on the right side of the left element) that I can't explain.
Edit 2
It's got to be transform - changing the border-color to red makes this clear: the border is being rendered at a sub-pixel level and then, for some reason, cut off in a funky way. You can see a vague pink border around the left input:
This may or may not help and without the fiddle, it's difficult to recreate; but I wanted to share something I've recently encountered with webkit browsers and Foundation.
By default, Foundation attaches a right float on the last column in each row or horizontal block...
foundation.css
[class*="column"] + [class*="column"]:last-child {
float: right; }
99% of the time this is never an issue, unless you have a very small border between columns. Webkit browsers calculate percentages strangely at times.
You mentioned your columns were floated left, but just in case this is still an issue; overriding the above pseudo class to float the last-child column left may help.
I'm quite new to web development and jQuery, so please bear with me.
I'm using Nivo Slider on a website that I'm working on. It's a responsive website, and I want the slider to be easily visible on all screen sizes. I've set a breakpoint in my CSS so that when the site gets to its smallest size (around the size of a mobile screen) the slider is set to 200% width, with the overflow hidden, so that the images are larger.
This works fine, however at this size you can only see the center of the slider, while the sides are cropped off by the edge of the screen. For most of the images I'm using this isn't a problem, however one of them is cropped very awkwardly. It's easy to reposition the whole slider, but I want to try and move this ONE image over so that it can be better seen on small screens.
The CSS I've added to the default nivo-slider.css is:
#media screen and (max-width: 31.25em) { /* 500px ÷ 16px */
.slider-wrapper{
overflow: hidden;
}
.nivoSlider {
left: -50%;
width:200%;
}
.nivo-caption {
margin-left: 25%;
width: 50%;
}
}
Thanks very much!
Just using CSS, you could add a one-off type class to that particular image, and throw that into your #media query:
.my-one-off { left:??px; margin-right:??px }
You could search for that image with jQuery as well (if I'm not mistaken, Nivo uses the jQ library).
$('img[src*="one-off.jpg"]').css('margin-left',35); // just an example
Or
$('img[src*="one-off.jpg"]').addClass('my-one-off');
I looked at nivo-slider3.1. In order to select a particular image only and move it left you could use the following in css:
img[src="YourSpecialPic.jpg"]{
left:50px !important;
}
You can also set a custom animation for one particular slide with the following img attribute within the HTML:
data-transition="slideInLeft"
You can sub any attributes to get the desired effect, but I think this will do the trick.
NOTE:
Depending on what effects you are using will determine whether or not that messes up the animation (e.g. The slicing animation becomes screwed up after performing the left move. The slideInLeft animation seems to work fine.).
I don't have a quick or easy solution for fixing all the animation effects for that one particular slide, but I'm sure a conditional statement within the javascript could achieve it (I'm just not smart enough for it).
I've checked other topics but I can't seem to figure this out. Testing this site here: http://www.mf.jlscs.com/
When in portrait view in Mobile Safari, I can scroll to the right to blank, white padding. I don't want this.
In landscape view, this scrolling isn't there and it renders as I'd like it.
I have no idea what is causing this mysterious push. I've tried to eliminate overflow-x, but that doesn't do the trick. If I eliminate overflow-x on each container, then this same effect is allowed to happen for every container in the page. Any ideas?
Just adding a border to some divs can cause the layout to change.
Add this to the bottom of your css to find the rogue element:
* {
background: #000 !important;
color: #0f0 !important;
outline: solid #f00 1px !important;
}
I also made a bookmarklet that does this through javascript so it can easily be used on any site. http://blog.wernull.com/2013/04/debug-ghost-css-elements-causing-unwanted-scrolling/
This is most probably caused by either one of your structural elements overshooting your body width. Look for code that is something like width: 100%; padding 20px; or something which would make it shoot out.
I suggest putting a red border on all the main divs and seeing which is the culprit and extends to the edge.
Indeed, this problem is due to "rogue" elements which extend outside of the document width for some reason.
One method is to use the CSS above, haven't tried, but I'm not sure how easy it would be to spot the elements using the borders.
A different approach would be to run this JS code in the console to find them:
Array.prototype.filter.call(document.querySelectorAll('*'), function (node) {
return node.clientWidth + node.offsetLeft > document.documentElement.clientWidth
});
This will return an array of all elements whos width + offset (distance from the left) are bigger than the clientWidth.
You would then need to inspect the elements and find out why they are behaving like this - in my case, the footer had width:100% and padding:10px, which caused its width to be 20px larger than the document width.
Interestingly enough, this was only seen on iPhones, not on Androids.
I would suggest downloading Web Developer for Firefox and just turning on Outline > Outline Block Level Elements.