Using calc inside max in SCSS [duplicate] - html

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

CSS calc() working inline but not in class [duplicate]

The Less compilers that I'm using (OrangeBits and dotless 1.3.0.5) are aggressively translating
body { width: calc(100% - 250px - 1.5em); }
into
body { width: calc(-151.5%); }
Which is obviously not desired. I'm wondering if there is a way to signal to the Less compiler to essentially ignore the attribute during compilation. I've searched through the Less documentation and both compilers' documentation, and I could not find anything.
Does Less or a Less compiler support this?
If not, is there a CSS extender that does?
Less no longer evaluates expression inside calc by default since v3.00.
Original answer (Less v1.x...2.x):
Do this:
body { width: calc(~"100% - 250px - 1.5em"); }
In Less 1.4.0 we will have a strictMaths option which requires all Less calculations to be within brackets, so the calc will work "out-of-the-box". This is an option since it is a major breaking change. Early betas of 1.4.0 had this option on by default. The release version has it off by default.
A very common usecase of calc is take 100% width and adding some margin around the element.
One can do so with:
#someMarginVariable = 15px;
margin: #someMarginVariable;
width: calc(~"100% - "#someMarginVariable*2);
width: -moz-calc(~"100% - "#someMarginVariable*2);
width: -webkit-calc(~"100% - "#someMarginVariable*2);
There is several escaping options with same result:
body { width: ~"calc(100% - 250px - 1.5em)"; }
body { width: calc(~"100% - 250px - 1.5em"); }
body { width: calc(100% ~"-" 250px ~"-" 1.5em); }
There's a tidier way to include variables inside the escaped calc, as explained in this post: CSS3 calc() function doesn't work with Less #974
#variable: 2em;
body{ width: calc(~"100% - #{variable} * 2");}
By using the curly brackets you don't need to close and reopen the escaping quotes.

How to implement simple layout: header - sidebar - content

I'm looking for a simple, effective and modern way to implement the following layout for a website:
- header: 100% width
- below header
- sidebar with fixed width
- content area that fills up till 100%
I've found a good example here, but this is all based on 'em' sizing, we have quite some backgroundpixels so we rather need an example with 'px'.
We thought that we could switch easily to 'px' in that specific example, but apparently it's not that easy to get this perfect.
Thanks in advance for all the tips!
You can use flex to have a sidebar on the left with a fixed width whereas the content on the right takes up the remaining space. Be aware that flex was added with CSS3 and older versions of Internet explorer may not support it (http://caniuse.com/#search=flex)
.contentContainer {
display:flex;
flex-direction: row;
}
.left {
background-color: #ffaa00;
min-width:200px;
}
.right {
background-color: #00aaaa;
flex:1;
}
https://jsfiddle.net/nrv5p70q/1/
However some simple googling could have solved the issue too. You may want to check this cheat sheet:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
The example you are using will allow you to achieve this.
You can use a em to px conversion to convert the values from em to px. Once you have the correct values you can replace them in the css. Thus.
#nav {
margin-left: -352px; //was -22em
margin-left: expression((-(document.getElementById("wrapper").clientWidth))+"px");
left: 208px; //was 13em;
}
Using this method will allow you to continuing w3schools tutorial which is a great way to get up to speed with html and css.

Shorthand to set height and width of an element in CSS

Basic question but I can't find it anywhere, is it possible to set the width and the height on the same line at the same time with the same value in my CSS?
I'm not asking for something like:
width:100%;height:100%;
But more like one of those:
width, height: 100%; // Same for both
width, height: 100%, 90%; // Different for each ones
dimensions: 100% 90%; // Like padding/margin,
I'm just asking about declaration, not Javascript on how to do that.
I found a related question to this one but for border and the short answer was no.
If it's not possible with CSS, is it with SCSS ?
There is no short hand for setting the height and width of the element in a single property declaration. You cannot do it with SASS as well.
But yea, SASS will provide you a feature to hold the common value shared in both property by declaring a variable like
$some-var-name: 100px;
.some-class {
height: $some-var-name;
width: $some-var-name;
}
As I said, even SASS won't help you writing height and width at the same time but you can use change the value of both from a single variable.
Ok I was about to add the #extend in the answer but since other user has already answered the same, (which is now deleted)
.size{
height:100%;
width:100%;
}
element {
#extend .size; //Sets element to height:100%;width:100%;
// more stuff here
}
I would suggest you to use a declaration of % instead of . so instead of using .size suggested use %size. This way your literal class of .size used only for extend purpose won't be included in the compiled stylesheet.
you can use css variable
/* css file */
:root {
--length: 50px;
--ratio: 1;
}
.box {
background: cornflowerblue;
width: calc(var(--ratio) * var(--length));
height: var(--length);
}
<!-- html file -->
<div class="box"></div>
then you can change --length in many ways and box width and height will respect to changes.
and Its better method than the SCSS variable for debugging purposes.
Articles
Comparison between CSS variable vs SCSS variable
Why we prefer CSS Custom Properties to SASS variables
You can set up Sass Mixin, like this:
#mixin size($width, $height) {
width: $width;
height: $height;
}
Then write just:
#include size(100%, 100%);
My little contribution if both w & h are equals :
div {
width: 100%;
aspect-ratio: 1;
}
This doesn't help much in typing, but with this, there is only one place to update.
To add onto the mixin solution by #Allrightman, you could even account for when the width and height are the same by setting a default value for the second parameter to equal the first:
#mixin size($width, $height: $width) {
width: $width;
height: $height;
}
If a user inputs a single value opposed to two, this will set them both to the same thing, covering both use cases.
There is no way to declare height and width at the same time in pure CSS, but you can use preprocessors css like SASS or LESS to declare the value to avoid repetition, but don't forget that after they get complied to CSS, they become pure CSS again...
Fo example in SASS you can do:
$width-height: 100%;
body {
height: $width-height;
width: $width-height;
}
So as you see, you can define it, but after it gets complied to CSS, it becomes like this again:
body {
height: 100%;
width: 100%;
}
But we all know this is not always the case, the CSS for the big applications could be much more complex, and reusing and declaring values using preprocessors css will help a lot to manage your css in a tidier way!...

CSS calc() in border-width?

Can I use calc() with border-width?
I would like the following CSS to work:
.my-element {
border-left-width: calc(10% + 10px);
border-right-width: calc(10% + 20px);
}
But for whatever reason, any value I provide with calc() results in no border at all. The documentation I've found on MDN aren't clear about whether calc can be used - it says that I should use Any <length> value, but does that include calc?
I target IE9, but I get the same results in Chrome 34 and Firefox 28. I know I can alsway use jQuery to achieve these things, but I want to avoid it if at all possible.
Unfortunately, border-width cannot use a % value as any % is NOT related to size of the element.
So, basically...NO you can't use calc WITH % for border-width because it doesn't know what it's supposed to be a % of.

Safari not rendering margin-top % values like other browsers

I have asked this question before, but thought I'll be clearer. It seems that margin-top in % value does not display the same on Safari, as it does on Chrome, Firefox and IE. In px it displays correctly and margin-left % also.
Here is an example to make comparisons: Fiddle
* {
margin:0;
padding:0;
}
.A {
background-color: blue;
height: 200px;
position:relative;
}
.B {
left: 50px;
margin-top:15%;
width:20px;
height:20px;
background-color: red;
position:absolute;
}
I really need to use a % value on margin-top as it is for a responsive design feature. Using top does not scale the object according to the window size.
Are there known issues, and if so (probably asking a big thing) a way to only target Safari as a browser so I can have custom values for the style sheet?
Yes, according to the W3C standards, margins defined using percentages should be calculated with respect to the width of the containing block.
Ref: (http://www.w3.org/TR/2011/REC-CSS2-20110607/box.html#margin-properties)
However, it appears that Safari calculates top/bottom margin percentages with respect to the height of the containing block, which makes more logical sense, but is nevertheless incorrect as far as W3 standards go.
I don't believe there is a CSS solution for this. You could try some jQuery to target only Safari, get the width of div.A and use it to calculate the margin-top for div.B.
Something like:
var width = $('.A').width();
var topMargin = width * 0.15;
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
$('.B').css('margin-top', topMargin+'px')
}
else {
};;
Here's an example page: http://www.indieweb.co.nz/testing/safari-margin-percentage.html
Note: This JS only alters the margin when the page is loaded - it won't change dynamically if you manually drag the edges of your browser window; you will need to refresh the page. Wasn't sure if you required that functionality. Let me know if you do and I'll have a look.