Compass: Exporting Sprites Positions as Percentages - responsive-design

When using compass' sprite generator, the generator creates CSS rules based on pixels.
Example code:
#import 'compass/utilities/sprites';
$sprite-2-layout: horizontal;
#import "sections/anatomy-sprite-test/sprite-2/*.png";
#include all-sprite-2-sprites;
$sprite-3-layout: horizontal;
#import "sections/anatomy-sprite-test/sprite-3/*.png";
#include all-sprite-3-sprites;
$sprite-4-layout: horizontal;
#import "sections/anatomy-sprite-test/sprite-4/*.png";
#include all-sprite-4-sprites;
Example Output:
/* line 84, ../../../../../../../../../../../Library/Ruby/Gems/2.0.0/gems/compass-core-1.0.1/stylesheets/compass/utilities/sprites/_base.scss */
.sprite-2-00 {
background-position: 0 0;
}
/* line 84, ../../../../../../../../../../../Library/Ruby/Gems/2.0.0/gems/compass-core-1.0.1/stylesheets/compass/utilities/sprites/_base.scss */
.sprite-2-00 {
background-position: -244px 0;
}
Is there a way in which these can be generated in percentages in order for them to be used responsively?
I've written my own, but it doesn't work well in certain browsers. Here's my approach:
#mixin sprite-percentage-step-generate($steps, $single_image_width) {
$total_image_width: ($single_image_width * $steps) - $single_image_width;
background-position: 0 0;
img {
display: none;
}
#for $i from 0 through ($steps - 1) {
$step_width: $i * $single_image_width;
&.step-#{$i} {
background-position: percentage(($step_width / $total_image_width)) 0;
// We include these to see the relation between the percentage and the step count
img {
display: none;
}
}
}
}
Maybe this is not a good idea, since the generator might do some special kind of optimization so that the pixel based approach works best?
Again, the question is: Is there a way to make Compass generate CSS in which the positions of the sprites are generated as percentages and not as pixels?

At the end, the solution was to make all the percentages have no decimal places or 1 decimal place. This works in all browsers beautifully.
For sprites that have a weird number of images (Let me clarify, that these sprites are all the same width) the solution is to make the image bigger. For example, if the image has 17 slides, the image can be extend to simulate 25, thereby creating percentages that are rendered correctly by the browser.

Related

Importing variables scss

I am using scss for the first time
I created a file in src/styles/variables.scss
$background-color: #323132;
Then on src/components/MyComponent.module.scss
#use "src/styles/variables";
.content {
background-color: variables.$background-color;
}
And I get
SassError: Invalid CSS after "...olor: variables": expected expression (e.g. 1px, bold), was ".$background-color;"
on line 14 of src/components/MyComponent.module.scss
>> background-color: variables.$background-color;
I can't find what is wrong? thank you
Just import your variables instead and use directly
#import "src/styles/variables";
.content {
background-color: $background-color;
}

Maximum call stack size exceeded from loop

I'm in the early stages of producing a rectangle SVG that uses the rectangle shape. I'm generating the colours of the pixels using a loop that gets all the RGB colours in increments of 8. The returned array has 32,768 <rect /> in it. The code produces the desired outcome however I get an error in:
Chrome
Maximum call stack size exceeded
getTypeSymbol (react_devtools_backend.js:4828)
Firefox
too much recursion
From what I can tell this isn't a recursion problem, the function doesn't appear to be reloading. I think it's related to the size of the array.
Any thoughts on what I should do here, I've never seen this problem before.
function PixelColour() {
console.log("start");
let counter = 0;
let x = 0;
let y = 0;
const colours = [];
for (let red = 0; red < 256; red += 8) {
for (let green = 0; green < 256; green += 8) {
for (let blue = 0; blue < 256; blue += 8) {
counter++;
if (x < 256) {
x++;
} else {
x = 0;
}
if (x === 256) {
y++;
}
colours.push(
<rect
key={counter}
x={x}
y={y}
height="1"
width="1"
style={{ fill: `rgb(${red}, ${green}, ${blue})` }}
/>
);
}
}
}
return <Fragment>{colours}</Fragment>;
}
class Colours extends React.Component {
render() {
return (
<div>
<svg width="256" height="128" style={{ border: "2px solid black" }}>
<PixelColour />
</svg>
</div>
);
}
}
It's not your function reloading (or rerendering) which is the problem per se; you're running into recursion within React itself. Specifically with the way that React devtools tries to reconcile the DOM in order to build a component map.
This is actually not so easy to replicate on codesandbox, since it appears to be using an experimental version of devtools, and this error only crops up when hot-reloading. The stack trace there is scheduleFibersWithFamiliesRecursively but on my local machine with the standard devtools extension installed I get mountFiberRecursively when the component mounts.
I did some digging and came across this github issue, and a PR addressing it which appears to have been abandoned for the time being.
Perhaps if you go and give them a nudge they might take another look:
Getting maximum call stack exceeded on backend.js when rendering many elements.
Refactored backend renderer to remove most of the recursion
All you can do in the meantime is disable the devtools extension. I would add that even with it disabled, this component takes several seconds to mount on my local machine. If you don't take the calculation out of the render cycle (function body) then it is going to be run on every render. You're trying to mount 10s of thousands of DOM nodes which is never going to run performantly - even the PR above only supposes a limit of 15000.
I think a better idea would be to 1) calculate this well in advance if you can, perferably as hard-coded data and nowhere near the UI thread, and 2) draw to a canvas rather than creating nodes in the DOM.

Less contrast() functions for Stylus

What is the Stylus version of the contrast() function used in Less? I need to provide legibility given a background color, and should be automatic no matter what given color.
AFAIK there is no direct equivalent. However there are many color functions like mixing, inverting, darkening etc to build a color to your own wishes.
The Stylus-owned contrast() function will tell you the current contrast ratio, which goes from 1 to 21 (higher is better). For more info see Stylus documentation.
Something like this works well for me:
var_backgroundColor = teal
var_fontColor = black
var_fontColorAlternative = darken(complement(var_backgroundColor),15%)
body { color: var_fontColor; background-color: var_backgroundColor }
if contrast(var_fontColor,var_backgroundColor).ratio <= 7 {
body { color: var_fontColorAlternative }
}
else {
body { color: var_fontColor }
}

Sass - loop through array of numbers for nth-child(#{$i}) targeting

I'm creating a mixin to hide columns (th and td) of nth-child value sent from the include statement. What's missing in my code, or better yet, is this the best approach even if corrected to work?
Include statement:
$hidden-columns: (2, 3, 6, 9, 17);
#include hide-columns($hidden-columns);
Mixin:
#mixin hide-columns($columns) {
#for $i from 0 to length($columns) {
th:nth-child(#{$columns[ $i ]}),
td:nth-child(#{$columns[ $i ]}) {
display: none;
}
}
}
I ended up using #each instead of a loop (below) however, I'd still love to know the correct syntax for the loop in my original post if someone cares to post and I will mark that as the answer.
#mixin hide-columns($columns) {
#each $col in $columns {
th:nth-child(#{$col}),
td:nth-child(#{$col}) {
display: none;
}
}
}

LESS dynamic variables in nested loops

I'm trying to achieve in LESS loops something in JS or PHP would be really simple. Lets say I have 4 levels to loop. Each level height depends on previous level height. Something like:
for (var i; i < 4; i++) {
if (i = 1) {
var height = 100 * i;
} else {
height = height * 3 - i * 20;
}
}
assignFinalHeight(height);
Is it even possible to achieve in LESS?
Tried guarded mixins something like this:
#height: 0;
.count(#lvl) when (#lvl > 1) {
.for(4); .-each(#lvl) {
#height: #height * 3 - #lvl * 20;
}
}
.count(#lvl) when (#lvl = 1) {
#height: 100 * #lvl;
}
.for(4); .-each(#lvl) {
.count(#lvl);
.lvl_#{lvl} {
height: #height;
}
}
Hope you get the idea.
I also tried some other techniques, but I get errors of recursive variable or I get generated CSS with first two levels correct and all other levels the same as second one.
Any help is appreciated
I'm trying to make something like a playoffs scheme - http://i.imgur.com/J8frRVg.png. All marked 2 team holders are div's with some css classes. All these holders are wrapped in one div. Like
<div>
<div class="holder lvl_1 pos_1">
<div class="team_1"></div>
<div class="other stuff"></div>
<div class="team_2"></div>
</div>
<div class="holder lvl_1 pos_2">...</div>
<div class="holder lvl_2 pos_1">...</div>
...
</div>
The only thing left, is the height and positions from top, but these depend on previous level height. Probably I will just make it in JS if it's not possible in LESS :/

Resources