skip to Main Content

I have relatively complex formulas e.g. transform: scale(var(--image-scale)) translateY(calc((1px * var(--element-height) * (var(--image-scale) - 1)) / 2 * var(--scrolled-out-y)))

how do I debug calculated value?
moreover is there a way to validate/highlight formulas errors?

I tried to output like this to the pseudoelement but no luck

    position: fixed;
    display: block;
    left:0;
    right: 0;
    background: yellow;
    padding: 5px;
    z-index: 100;
    content: calc((1px * var(--element-height) * (var(--image-scale) - 1)) / 2 * var(--scrolled-out-y));

the only way I found is to put part of calculation to unused numeric property e.g. background-position-x on the gif below so it will show calculated value on computed tab – useful but not really convenient one (notice background-position-x changes while the page scrolls):

enter image description here

var sc = ScrollOut({
    cssProps: true
  })
  const results = Splitting();

  var parallaxedElements = document.querySelectorAll('.section');

  document.addEventListener('scroll', function(e) {
    parallaxedElements
    Array.from(parallaxedElements).forEach((el) => {
      var bcr = el.getBoundingClientRect();
      if (bcr.y < 0 && Math.abs(bcr.y) <= bcr.height) {
        el.style.setProperty("--scrolled-out-y", Math.round(Math.abs(bcr.y) * 10000 / bcr.height) / 10000);
      }
    });

  })
@import url("https://fonts.googleapis.com/css?family=Roboto");
  html {
    scroll-behavior: smooth;
  }
  
  body {
    font-family: "Roboto";
    font-size: 14px;
    line-height: 1.4;
    scroll-behavior: smooth;
  }
  
  .section {
    position: relative;
    background-attachment: fixed;
    z-index: 1;
    --image-scale: 1.2;
    --scrolled-out-y: 0;
  }
  
  .section__background {
    position: -webkit-sticky;
    position: sticky;
    top: 0;
    width: 100%;
    height: 100vh;
    overflow: hidden;
  }
  
  .section__background:after {
    content: "";
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    top: 0;
    z-index: 1;
    background: linear-gradient(to bottom, black, 100% white);
    background: rgba(0, 0, 0, 0.4);
    opacity: calc(1 + ((var(--viewport-y) * 1.5)));
  }
  
  .section__background>img {
    height: 150vh;
    width: 100%;
    object-fit: cover;
    position: absolute;
    left: 0;
    top: 0px;
    user-select: none;
    transform: scale(var(--image-scale)) translateY(calc((-1px * var(--element-height) * (var(--image-scale) - 1)) * var(--scrolled-out-y)));
  }
  /* .indicator:after {
        position: fixed;
        display: block;
        left: 0;
        right: 0;
        background: pink;
        padding: 5px;
        z-index: 100;
        content: calc((1px * var(--element-height) * (var(--image-scale) - 1)) / 2 * var(--scrolled-out-y));
    } */
  
  .section__container {
    padding-bottom: 50vh;
    overflow: hidden;
    align-items: flex-start;
    position: relative;
    z-index: 4;
  }
  
  .section__heading {
    color: #fff;
    text-transform: uppercase;
    font-size: 45px;
    line-height: 1.2;
    font-weight: 800;
    letter-spacing: 8px;
    margin: 0;
    overflow: hidden;
    position: relative;
    padding-bottom: 50px;
    margin-bottom: 50px;
  }
  
  .section__heading:after {
    content: "";
    position: absolute;
    top: 200px;
    left: 0;
    right: 0;
    height: 2px;
    transform: translateX(calc(var(--scrolled-out-y) * 100% - 70%));
    background: #b38c6b;
  }
  
  .section__content {
    display: flex;
    color: white;
    flex-direction: column;
  }
  
  .section__content p+p {
    margin-top: 20px;
  }
  
  .splitting {
    --char-percent: calc(var(--char-index) / var(--char-total));
  }
  
  .splitting .char {
    display: inline-block;
    opacity: calc(1 + ((var(--viewport-y) * 1.5) - var(--char-percent)));
  }
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css'>
<link rel='stylesheet' href='https://unpkg.com/splitting/dist/splitting.css'>

<section data-scroll class="section section-1">
  <div class="section__background">
    <div class="indicator"></div>
    <img src="https://picsum.photos/1920/1079" alt="placeholder image" />
  </div>
  <div class="container section__container">
    <div class="row">
      <div class="title-block col-md-6 d-flex">
        <h1 data-scroll data-splitting class="section__heading">
          Why <br>CSS <br>matters
        </h1>
      </div>
      <div class="col-md-6 d-flex">
        <div class="section__content">
          <p>
            MThe ability to use variables in CSS is a useful and powerful feature that web developers have long been asking for. Well, it has finally arrived, and it’s awesome!
          </p>
          <p>
            In this article we’ll look at the history, importance, and use of CSS variables, and how you can leverage them to make your CSS development and maintenance faster and easier.
          </p>
          <p>
            Keep reading and you will understand why.
          </p>
          <div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>

<section data-scroll class="section section-2">
  <div class="section__background">
    <img src="https://picsum.photos/1920/1081" alt="placeholder image" />
  </div>
  <div class="container section__container">
    <div class="row">
      <div class="title-block col-md-6 d-flex">
        <h1 data-scroll data-splitting class="section__heading">
          Why <br>CSS <br>matters
        </h1>
      </div>
      <div class="col-md-6 d-flex">
        <div class="section__content">
          <p>
            MThe ability to use variables in CSS is a useful and powerful feature that web developers have long been asking for. Well, it has finally arrived, and it’s awesome!
          </p>
          <p>
            In this article we’ll look at the history, importance, and use of CSS variables, and how you can leverage them to make your CSS development and maintenance faster and easier.
          </p>
          <p>
            Keep reading and you will understand why.
          </p>
          <div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>

<section data-scroll class="section section-3">
  <div class="section__background">
    <img src="https://picsum.photos/1920/1082" alt="placeholder image" />
  </div>
  <div class="container section__container">
    <div class="row">
      <div class="title-block col-md-6 d-flex">
        <h1 data-scroll data-splitting class="section__heading">
          Why <br>CSS <br>matters
        </h1>
      </div>
      <div class="col-md-6 d-flex">
        <div class="section__content">
          <p>
            MThe ability to use variables in CSS is a useful and powerful feature that web developers have long been asking for. Well, it has finally arrived, and it’s awesome!
          </p>
          <p>
            In this article we’ll look at the history, importance, and use of CSS variables, and how you can leverage them to make your CSS development and maintenance faster and easier.
          </p>
          <p>
            Keep reading and you will understand why.
          </p>
          <div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>


<section data-scroll class="section section-4">
  <div class="section__background">
    <img src="https://picsum.photos/1920/1083" alt="placeholder image" />
  </div>
  <div class="container section__container">
    <div class="row">
      <div class="title-block col-md-6 d-flex">
        <h1 data-scroll data-splitting class="section__heading">
          Why <br>CSS <br>matters
        </h1>
      </div>
      <div class="col-md-6 d-flex">
        <div class="section__content">
          <p>
            MThe ability to use variables in CSS is a useful and powerful feature that web developers have long been asking for. Well, it has finally arrived, and it’s awesome!
          </p>
          <p>
            In this article we’ll look at the history, importance, and use of CSS variables, and how you can leverage them to make your CSS development and maintenance faster and easier.
          </p>
          <p>
            Keep reading and you will understand why.
          </p>
          <div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>

<section data-scroll class="section section-5">
  <div class="section__background">
    <img src="https://picsum.photos/1920/1084" alt="placeholder image" />
  </div>
  <div class="container section__container">
    <div class="row">
      <div class="title-block col-md-6 d-flex">
        <h1 data-scroll data-splitting class="section__heading">
          Why <br>CSS <br>matters
        </h1>
      </div>
      <div class="col-md-6 d-flex">
        <div class="section__content">
          <p>
            MThe ability to use variables in CSS is a useful and powerful feature that web developers have long been asking for. Well, it has finally arrived, and it’s awesome!
          </p>
          <p>
            In this article we’ll look at the history, importance, and use of CSS variables, and how you can leverage them to make your CSS development and maintenance faster and easier.
          </p>
          <p>
            Keep reading and you will understand why.
          </p>
          <div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>


<section data-scroll class="section section-6">
  <div class="section__background">
    <img src="https://picsum.photos/1920/1085" alt="placeholder image" />
  </div>
  <div class="container section__container">
    <div class="row">
      <div class="title-block col-md-6 d-flex">
        <h1 data-scroll data-splitting class="section__heading">
          Why <br>CSS <br>matters
        </h1>
      </div>
      <div class="col-md-6 d-flex">
        <div class="section__content">
          <p>
            MThe ability to use variables in CSS is a useful and powerful feature that web developers have long been asking for. Well, it has finally arrived, and it’s awesome!
          </p>
          <p>
            In this article we’ll look at the history, importance, and use of CSS variables, and how you can leverage them to make your CSS development and maintenance faster and easier.
          </p>
          <p>
            Keep reading and you will understand why.
          </p>
          <div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>
<script src='https://unpkg.com/scroll-out/dist/scroll-out.min.js'></script>
<script src='https://unpkg.com/[email protected]/dist/splitting.js'></script>

2

Answers


  1. Is there a way to validate/highlight formulas errors?

    You need to check to see if you aren’t breaking any rules when defining your formula. Here it is from the specification:

    At each operator, the types of the left and right argument are checked for these restrictions. If compatible, the type resolves as described below (the following ignores precedence rules on the operators for simplicity):

    • At + or -, check that both sides have the same type, or that one side is a <number> and the other is an <integer>. If both sides are the same type, resolve to that type. If one side is a <number> and the other is an <integer>, resolve to <number>.
    • At *, check that at least one side is <number>. If both sides are <integer>, resolve to <integer>. Otherwise, resolve to the type of the other side.
    • At /, check that the right side is <number>. If the left side is <integer>, resolve to <number>. Otherwise, resolve to the type of the left side.

    If an operator does not pass the above checks, the expression is invalid

    It may sound a bit complex at the start but the rules are easy, and we can re-write them as follows with easy words:

    • You cannot add/subtract two different types (5px + 5s has no meaning).
    • You can only multiply with a number (5px * 5px has no meaning and is not equal to 25px).
    • You can only divide with a number that isn’t 0 (5px / 5px has no meaning and it’s not equal to 1 or 1px).

    If you don’t break any of these rules, then your formula is correct. Let’s not forget another important syntax rule:

    In addition, white space is required on both sides of the + and – operators. (The * and / operaters can be used without white space around them.)


    Consider this, you simply need to identify if your CSS variable is a number/integer or defined with a type (length, frequency, angle or time). If it’s not defined or contains a string value then the calc() will be invalid.

    Check the specification for more details and a more precise explanation: https://drafts.csswg.org/css-values-3/#calc-type-checking


    How do I debug calculated value?

    To check the computed value, I don’t think there is a way because the computed value of calc() can be different depending where you use it (which property). In other words, the final value doesn’t exist until it’s been used within a property.

    We may think that some formulas are trivial like calc(5px + 5px) which will always compute to 10px but other ones will be more difficult. Like calc(5px + 50%) where % will behave differently based on a property. Considering this, the browser will never compute the value until it’s used within a property.

    Even with the use of JS you cannot have the final value you want to debug; you can only get a computed value of properties:

    var elem = document.querySelector(".box");
    var prop = window.getComputedStyle(elem,null).getPropertyValue("--variable");
    var height = window.getComputedStyle(elem,null).getPropertyValue("height");
    console.log(prop);
    console.log(height);
    .box {
      --variable: calc(5px + 5px);
      height:var(--variable);
    }
    <div class="box"></div>
    Login or Signup to reply.
  2. So to actually debug CSS variables you can use the helper class that I added below.

    So then in console you set and read variable like so:

    CssVariables.setRootVar('--column-max-width', 'calc((90vw - var(--zoomer-width)) / (var(--columns-shown) + 1))');
    console.log('width:', CssVariables.getRootVar("--column-max-width"));
    

    Note that when you read a variable var(--) is already resolved.

    When formula is invalid you will probably get a warning on console.

    CssVariables.setRootVar('--column-max-width', 'calc(123px - var(123))');
    // -> invalid value, declaration skipped
    

    When you e.g. use non-existent variable you will get empty string when reading.

    CssVariables.setRootVar('--column-max-width', 'calc(123px - var(--wtf))');
    console.log('width:', CssVariables.getRootVar("--column-max-width"));
    // -> width: <empty string>
    

    The CssVariables helper

    /**
     * CSS variables helper.
     */
    class CssVariables {
        /**
         * Get :root variable.
         * @param {String} name Name of CSS var. e.g. "--columns-shown".
         * @returns {String} Current value.
         */
        static getRootVar(name) {
            return this.getVar(document.documentElement, name);
        }
        /**
         * @see #getRootVar
         */
        static getVar(element, name) {
            return window.getComputedStyle(element, null).getPropertyValue(name);
        }
        /**
         * Set :root variable.
         * @param {String} name Name of CSS var. e.g. "--columns-shown".
         * @param {String} value New value. Should be a strin, but numbers would work as well.
         */
        static setRootVar(name, value) {
            this.setVar(document.documentElement, name, value);
        }
        /**
         * @see #setRootVar
         */
        static setVar(element, name, value) {
            element.style.setProperty(name, value);
        }
    }
    
    // if you are working with modules
    //export { CssVariables }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search