Grow your CSS skills. Land your dream job.

[Solved] Understanding and using CALC()

  • # March 19, 2014 at 5:58 am

    Hi guys, am new here and wondering if someone can give me a nudge in the right direction.

    I am looking at the CALC() function and am banging my head against a wall at the moment.

    What I am attempting to do (and understand) is a basic grid

    I have the grid set-up using “%” for the width and margin e.g. Width: 978px = 100%, Margin left: 30px = 3.06748466257669%

    I would like to use calc for modern browsers that support it

    My CSS setup in basic form:

    .half, .third, .quarter, .fifth, .sixth{display:block; float:left; margin:0 0 0 3.06748466257669%;}
    .first{margin-left:0; clear:left;}
    
    .half{width:48.46625766871166%;}
    .third{width:33.33333333333333%;}
    .quarter{width:22.69938650306748%;}
    .fifth{width:17.54601226993865%;}
    .sixth{width:14.11042944785276%;}
    

    Markup would be something like this:

    <div class="row clear">
      <div class="third first">1</div>
      <div class="third">2</div>
      <div class="third">3</div>
    </div>
    

    Using calc for the margin would be: margin:0 0 0 calc(30px/978px * 100%)

    But getting the rest to work using CALC is just not happening, I get the feeling I simply don’t understand the function

    Any and all help is much appreciated.

    # March 19, 2014 at 6:12 am

    Chis just did a video on this sort of thing…it’s not precisely on point but it might give you some ideas: http://css-tricks.com/video-screencasts/132-quick-useful-case-sass-math-mixins/

    However I think as a general rule the function would be

    calc(30px / 978px)

    Note the spacing…I think that’s important.

    Note: The + and – operators must always be surrounded by whitespace. The operand of calc(50% -8px) for instance will be parsed as a percentage followed by a negative length, an invalid expression, while the operand of calc(50% – 8px) is a percentage followed by a minus sign and a length. Even further, calc(8px + -50%) is treated as a length followed by a plus sign and a negative percentage.
    The * and / operators do not require whitespace, but adding it for consistency is allowed, and recommended.

    https://developer.mozilla.org/en-US/docs/Web/CSS/calc

    # March 19, 2014 at 6:37 am

    @Paulie_D

    Thanks for the feedback, I will take a look at the screencast shortly.

    Ive taken my info from: http://www.w3.org/TR/css3-values/#calc

    As can be seen in Example 12, the “/” sign doesn’t have space, whereas the rest “+”, “-” etc. do

    # March 19, 2014 at 8:05 am

    Perhaps it might be better if you gave us a Codepen to play with so we can experiment.

    # March 19, 2014 at 8:17 am

    I havent used Codepen before and wouldnt know where to start :)

    BUT:

    After viewing the screencast I think this is correct:

    .half{width:calc((100% - (1 * 3.06748466257669%)) / 2);}
    .third{width:calc((100% - (2 * 3.06748466257669%)) / 3);}
    .quarter{width:calc((100% - (3 * 3.06748466257669%)) / 4);}
    .fifth{width:calc((100% - (4 * 3.06748466257669%)) / 5);}
    .sixth{width:calc((100% - (5 * 3.06748466257669%)) / 6);}
    

    Im finding the logic is my problem – understanding what is actualy required and what’s happening.

    I am by no means a math expert but looking at the equations above 3 things go on:

    Step 1
    margin amount multiplied by margin width e.g. (1 * 3.06748466257669%) = 3.06748466257669%

    Step 2
    100% width minus the result of margin amount multiplied by margin width e.g. (100% – (1 * 3.06748466257669%) = 96.93251533742331%

    Step 3
    The result of Step 1 + 2 divided by the amount of elements to be displayed e.g. ((100% – (1 * 3.06748466257669%)) / 2) = 96.93251533742331% / 2 = 48.46625766871166%

    I have tried following suit, with, for example “twothird” & “threequarter”, but my result seems to be clumsy and long winded:

    .twothird{width:calc((100% - (2 * 3.06748466257669%)) / 3 * 2 + 3.06748466257669%);}
    
    .onequarter{width:calc((100% - (3 * 3.06748466257669%)) / 4);}
    .twoquarter{width:calc((100% - (3 * 3.06748466257669%)) / 4 * 2 + 3.06748466257669%);}
    .threequarter{width:calc((100% - (3 * 3.06748466257669%)) / 4 * 3 + 2 * 3.06748466257669%);}
    
    # March 19, 2014 at 8:28 am

    A couple things come to mind here. First why don’t you use something a little simpler. For example checkout how bootstrap accomplishes the grid: http://getbootstrap.com/css/#grid

    Chris also has a good example here: http://css-tricks.com/dont-overthink-it-grids/

    Also, keep in mind that because of browser support anytime you want to use calc(); you also need to use -webkit-calc(); for older versions of Chrome & Safari. For more info on browser support: https://developer.mozilla.org/en-US/docs/Web/CSS/calc

    # March 19, 2014 at 8:32 am

    Hi,

    I don’t really see how calc benefits you here as you know what dimensions you need as you have them all in percent. If on the other hand you wanted to take 30px away from 33.33% for example then calc() would be useful.

    I don’t like all those decimal points as css was never meant to be used that way and browsers aren’t exactly brilliant at handling those fractions anyway. :)

    I assume you were doing something like this.

    http://www.codepen.io/paulobrien/full/dyEGe/

    However calc() isn’t really necessary as you could resolve those calculations beforehand anyway. If on the other hand you wanted a 30px gutter on a fluid layout then you could use calc (e.g. for 3 columns calc((100% – 60px) / 3)).

    Or did I miss the point :)

    [edit]
    Our posts crossed.:)
    [/edit]

    # March 19, 2014 at 8:48 am

    @paulob

    I’ve just looked at your work and see that it’s basicaly the same as my result – which is of course great news :) at least for me :)

    I want to slowly move away from all the decimal points, as you have stated, they are not 100% in all browsers.

    You are right, I would like to use 30px instead of uing the percent value and the rest should be completed with calc.

    But im still not sure if the rest of my calculations / equations are correct or if they could be simplified.

    # March 19, 2014 at 9:12 am

    Hi,

    Yes the basic examples were the same as yours :)

    For twothirds I would think you would need this:

    .twothirds{width:calc((100% / 3 * 2)  - 3.0675% / 3)}
    

    That’s if you want it to match up alignment with two single thirds.

    # March 19, 2014 at 9:24 am

    Your solution works – but I don’t understand it fully :(

    Step 1:
    (100% / 3 * 2) = I understand

    Step 2:
    - 3.0675% / 3 = don’t understand

    Step 1 = gives me the default size of 2/3
    Step 2 = removes one margin width and is then divided by 3

    Where does the 3 come from in step 2 ?

    # March 19, 2014 at 10:34 am

    Where does the 3 come from in step 2 ?

    It will be easier to visualise if for .third we say this instead:

    .third {width:calc((100% / 3)  -  2 * 3.0675% / 3) }
    

    That says divide into three and then distribute the 2 gaps over the three elements.

    So that follows when you want two thirds you do the same but you only want one gap distributed (over what would have been three elements).

    .twothirds{width:calc((100% / 3 * 2)  - 3.0675% / 3)}
    

    Does that make sense?

    There are other ways to do it but are longer:

    .twothirds{width:calc((100% – (2 * 3.0675%)) / 3 * 2 + 3.0675%)}

    I’m sure a someone better at maths can shorten the whole thing anyway :)

    # March 19, 2014 at 3:07 pm

    @paulob

    Thanks for the info, but I sill don’t follow, am obviously not the math/logic person I thought I was :)

    I am going the longer route (which I previously added) which I can understand and follow. There is probably a better cleaner way to do what I want, but I will stick to what I understand, as I have to teach those who use my work as well.

    Ive dropped the “%” margin for 30px and have tested with the results I expected.

    Example:

    .onequarter{width:calc((100% - (3 * 30px)) / 4);}
    .twoquarter{width:calc((100% - (3 * 30px)) / 4 * 2 + 30px);}
    .threequarter{width:calc((100% - (3 * 30px)) / 4 * 3 + 2 * 30px);}
    

    Obviously Calc is still an “in work” element for some browsers, but knowing how to use it does open things for the future.

    Cheers & Thanks for your help

    # March 20, 2014 at 2:34 am

    Thanks for the info, but I sill don’t follow, am obviously not the math/logic person I thought I was :)

    No worries, I had to stare at it for a while to work out why it was working :)

    # March 20, 2014 at 11:12 am

    dont forget one of the IEs has issues using decimal places past two…

Viewing 14 posts - 1 through 14 (of 14 total)

You must be logged in to reply to this topic.

*May or may not contain any actual "CSS" or "Tricks".