I want to be able to do the following:
height: 25% - 5px;
Obviously when I do that I get the error:
Incompatible units: 'px' and '%'.
Sass cannot perform arithmetic on values that cannot be converted from one unit to the next. Sass has no way of knowing exactly how wide "100%" is in terms of pixels or any other unit. That's something only the browser knows.
You need to use calc() instead. Check browser compatibility on Can I use...
.foo {
height: calc(25% - 5px);
}
If your values are in variables, you may need to use interpolation turn them into strings (otherwise Sass just tries to perform arithmetic):
$a: 25%;
$b: 5px;
.foo {
width: calc(#{$a} - #{$b});
}
There is a calc function in both SCSS [compile-time] and CSS [run-time]. You're likely invoking the former instead of the latter.
For obvious reasons mixing units won't work compile-time, but will at run-time.
You can force the latter by using unquote, a SCSS function.
.selector { height: unquote("-webkit-calc(100% - 40px)"); }
$var:25%;
$foo:5px;
.selector {
height:unquote("calc( #{$var} - #{$foo} )");
}
IF you know the width of the container, you could do like this:
#container
width: #{200}px
#element
width: #{(0.25 * 200) - 5}px
I'm aware that in many cases #container could have a relative width. Then this wouldn't work.
Sorry for reviving old thread - Compass' stretch with an :after pseudo-selector might suit your purpose - eg. if you want a div to fill width from left to (50% + 10px) of screen you could use (in SASS indented syntax):
.example
background: red
+stretch(0, -10px, 0, 0)
&:after
+stretch(0, 0, 0, 50%)
content: ' '
background: blue
The :after element fills 50% to the right of .example (leaving 50% available for .example's width), then .example is stretched to that width plus 10px.
Just add the percentage value into a variable and use #{$variable}
for example
$twentyFivePercent:25%;
.selector {
height: calc(#{$twentyFivePercent} - 5px);
}
Related
There is a grid span(12)
There are two blocks of text
.main-container
.content text text text text text text text text text
.sidebar text text text text text text text text text
Want to do so
Write the code
span(6 at 1) //
span(3 as 9) //
But don't get desired. Here's the whole code.
$debug: (image: show, color: rgba(#66f, .25), output: background, toggle: top right)
$susy: (columns: 12, gutters: 1/4, math: fluid, gutter-position: inside, debug: $debug)
.main-container
#include container(80%)
.content
width: 100%
height: 100%
#include span(6 at 1)
.sidebar
width: 100%
height: 100%
#include span(3 at 9)
I thought that the flag at designed exactly for this purpose. But experiment has shown that I'm wrong. On this question - how to work with the flag at? ow to achieve the desired result using the at?
The at flag is only used in this way for isolation output ('output': 'isolate'). That's because floats are relative, and Susy doesn't know their original position unless you isolate them. Isolation is useful in some cases, but it's better to use push and pull to move floated elements into relative positions when needed. Something like this:
.content {
height: 100%;
#include span(6);
#inlcude push(1);
}
.sidebar {
height: 100%;
#include span(3);
#include push(1);
}
If you do use isolation, it would be something like this:
.content {
height: 100%;
#include span(isolate 6 at 2); // position is 1-indexed
}
.sidebar {
height: 100%;
#include span(isolate 3 at 9);
}
I removed width: 100% because span overrides width anyway.
I have a funky element on an html page that I am having trouble selecting with an XPath query. I am using Capybara, however I hope this is an XPath problem. Possibly the - character needs escape or bad query?
HTML Element
<ins class="iCheck-helper" style="position: absolute; top: 0%; left: 0%; display: block; width: 100%; height: 100%; margin: 0px; padding: 0px; border: 0px; opacity: 0; background: rgb(255, 255, 255);"></ins>
XPath
"//*[contains(#class, 'iCheck-helper')]"
Ruby/Capybara
elements = all(:xpath, myXPathQuery) (documentation)
elements.Count is a Capybara::Result. elements.count returns 0 and I expect 1.
Is there a specific reason you need to do this as XPath? Capybara supports CSS selectors which are much easier to write for class names.
elements=all(:css, '.iCheck-helper')
Also when using all it returns immediately by default since it assumes no elements is a valid result. If your page is dynamically changing and you know you are want at least one element you should do
elements=all(:css, '.iCheck-helper', minimum: 1)
which will wait up to Capybara.default_wait_time seconds for at least one matching element to appear. You could also pass count: 1 (instead of minimum) if you know for sure you only want one element and any more than that should be an error, although in that case #find probably makes more sense
I have just noticed your CSS which is scrolled off to the right which has opacity: 0 - In any of the real browser drivers (selenium, capybara-webkit, poltergeist, etc - basically anything but racktest) that will make the element invisible so it will not be found by default. To find that element you can do
elements=all(:css, '.iCheck-helper', minimum: 1, visible: :all)
Please note that since Capybara is meant to emulate a real user, finding invisible elements is usually not a good thing since a real user couldn't see it or interact with it. Its generally a better idea to perform whatever action would make that element visible and then check for its existence/interact with it.
Try:
myXPathQuery = '//ins[#class="iCheck-helper"]'
elements = all(:xpath, myXPathQuery)
I've spent the past 4 hours trying to find a way to create a sprite image with Compass and sass that also automatically scales each individual image for use with the background-size property.
Nothing I've found works, can't believe it's that difficult.
Does any one have a working example?
Edit: This is what I have so far
#mixin resize-sprite($map, $sprite, $percent) {
$spritePath: sprite-path($map);
$spriteWidth: image-width($spritePath);
$spriteHeight: image-height($spritePath);
$width: image-width(sprite-file($map, $sprite));
$height: image-height(sprite-file($map, $sprite));
#include background-size(ceil($spriteWidth * ($percent/100)) ceil($spriteHeight * ($percent/100)));
width: ceil($width*($percent/100));
height: ceil($height*($percent/100));
background-position: 0 floor(nth(sprite-position($map, $sprite), 2) * ($percent/100) );
}
#mixin resize-sprite-set($map, $percent, $only...) {
$name: sprite_map_name($map);
#each $sprite in sprite_names($map) {
#if length($only) == 0 or index($only, $sprite) != false {
.#{$name}-#{$sprite} {
#include resize-sprite($map, $sprite, $percent);
}
}
}
}
The mixin returns no errors.
$my-icons-spacing: 10px; // give some space to avoid little pixel size issues on resize
#import "my-icons/*.png";
$my-icons-sprite-dimensions: true;
#include all-my-icons-sprites;
// the fun part
.small-icons { // overriding all sprites
#include resize-sprite-set($my-icons-sprites, 40); // 40% sized
}
.some-part-of-my-site {
#include resize-sprite-set($my-icons-sprites, 40, logo, ok); // will create overrides only for sprites "logo" and "ok"
}
I get the following error message from the above implementation when I try to compile. Via Prepros App.
remove ../images/my-icons-s9e77ab1ef1.png
create ../images/my-icons-s9e77ab1ef1.png
error style.scss (Line 62 of _mixins.scss: Undefined mixin 'resize-sprite-set'.)
identical ../css/style.css
I've also done some research on this. This gist is what I came up with:
https://gist.github.com/apauly/7917906
Update:
The solution depends on three key-parts:
scale width
scale height
get background-position
0.
Grab the dimensions for both, the complete sprite and the single icon:
$icon-file: sprite-file($map, $icon);
$icon-width: image-width($icon-file);
$icon-height: image-height($icon-file);
$sprite-file: sprite-path($map);
$sprite-width: image-width($sprite-file);
$sprite-height: image-height($sprite-file);
1.
Consider a div displaying a sprite as its background. Set background-size: 100%; to make sure, that the background sprite covers the full width of the div.
If one would use width: 100%;, the result would be something like this:
+----------------+
|--| |
|----------------|
|--------| | <--- This is the sprite image we want to display
|------| |
+----------------+
So we need to enlarge our background to get something like this: (the div should have overflow:hidden though)
+----------------+
|---------| |
|-----------------------|
|----------------| | <---
|-------------| |
+----------------+
To achieve that, just divide the width of the complete sprite by the width of the single icon:
width:percentage($sprite-width / $icon-width);
2.
This one is basically inspired by a blog post form tkenny:
http://inspectelement.com/tutorials/a-responsive-css-background-image-technique/
The resulting sass code is this:
display: block;
height: 0;
padding-bottom: percentage($icon-height / $icon-width);
background-size: 100%;
3.
The rest is just some basic math to calculate the top spacing of the icon inside of the sprite as a relative value:
Get the space from the top in pixels (a negative value):
$space-top:floor(nth(sprite-position($map, $icon), 2));
Sass will need a px-value
#if $space-top == 0 {
$space-top: 0px
}
Set the background position with percentages:
background-position:0 percentage(
-1 * $space-top / ( $sprite-height - $icon-height )
);
Here's a mixin for resizing sprites that works beautifully
#mixin resize-sprite($map, $sprite, $percent) {
$spritePath: sprite-path($map);
$spriteWidth: image-width($spritePath);
$spriteHeight: image-height($spritePath);
$width: image-width(sprite-file($map, $sprite));
$height: image-height(sprite-file($map, $sprite));
#include background-size(ceil($spriteWidth * ($percent/100)) ceil($spriteHeight * ($percent/100)));
width: ceil($width*($percent/100));
height: ceil($height*($percent/100));
background-position: 0 floor(nth(sprite-position($map, $sprite), 2) * ($percent/100) );
}
and the github it came from:
https://gist.github.com/darren131/3410875
hey guys,
somehow i can't find the solution for my little problem.
i have a paragraph setting with a max-width of 630px.
in some cases i have images within one of those paragraphs - and in this case i want the image to act normal -> without any max-width setting.
.post-body p {
width:99%;
max-width: 630px;
}
.post-body p img{
max-width:100% !important;
}
is it even possible to have the image larger than the max-width setting that's set to it's parent? do i need to use javascript (jquery)?
thank you for your help.
Unless you're modifying the image width some other way, as long as you don't do anything to the image it will display at full size.
See here: http://jsfiddle.net/WrfQQ/
I didn't bother declaring any CSS for the image, so it, by default, will show up at full size. (Please note, for the sake of testing I decreased the width of the p to 100px)
As I can see the problem is that you put a MAX-width to the img... you have to code the relative width... so:
.post-body p img{
position: relative;
width: 100%;
}
if you want it in jQuery the code is the below:
$('.post-body p img').width() == $('.post-body p').width();
I have an outer div with a variable height (and max-height) that's set with a specific pixel amount by JavaScript, containing two divs within.
The 1st div is intended to hold a variable amount of content, e.g. a list of links. It has no height set.
The 2nd div is intended to hold a fixed amount of content, and has a specific height set.
Right now, the max-height isn't working. The 1st div keeps growing, even with overflow: auto; set, and pushes the 2nd div below it outside the bounds of the outer div. How can I make it so that when the 1st div gets too large for the outer div to contain both it and the fixed-height 2nd div, the 1st div will start to scroll?
Example page: http://thevastdesign.com/scrollTest.html
Thanks for any help. I'd appreciate a CSS solution the most, even if it requires some hacks. It only has to work in Firefox 3+, IE8, and IE7.
Ideas?
You cant really do that without JS. Your max-height on the outer-div isnt going to control the height of one of your inner divs to invoke its scrolling. That inner div is always going to be the height you set (pixels, auto, etc..). You can either make the entire outer div scroll as needed by using overflow: auto or you can set a max height on the first inner div and set the overflow.
Given your setup, I would do the following (class names are implied by your question, not taken from the linked source):
div.outer {
position: relative;
max-height: $length(y);
overflow: hidden;
}
div.innerFixed {
position: absolute;
bottom: 0;
height: $length(y);
overflow: hidden; /* just in case, to keep things from
blowing out into all manner of crazy */
}
div.innerFlex {
max-height: $length(y);
overflow: auto;
}
These rules don't address box properties, which will have an impact on the height values that you apply. The combined height values (with box values included) of .innerFixed and .innerFlex should equal the height value of the container.
If you want to get all Zen and flip the vertical composition, you do that by swapping bottom for top on .innerFixed and assigning margin-top or padding-top to .innerFlex.
Something else I noticed is that you've got
div.outer { float: left; }
...But given what you need from that element (and to set the right content priority) I would instead suggest that you put your big column first in the source order and apply
div.mainContent {
float: right;
width: $length(x);
}
div.outer { /* i.e., the column that started the discussion */
margin-right: length(x);
}
with the understanding that the margin-right of the latter is somewhat greater than the width of the former (greater to account for the gutter between the two elements). Try it, you'll like it.