288

I have this html:

<div class="container h-screen w-screen">
  <div class="navBar h-7"></div>
  <div class="content-container"></div>
</div>

I have set the .navBar's height to h-7. Now I want to set .content-container's height to 100vh-(h-7).

How can I use calc() to set it?

1
  • From TailwindCSS v4 can use @utility directive for create a specially 100vh - h-{number} value as h-screen-minus-{number} class. Show utilities here. Commented Mar 31 at 16:14

10 Answers 10

626

Don't put space in calc:

class="w-[calc(100%+2rem)]"

Output:

.w-\[calc\(100\%\+2rem\)\] {
  width: calc(100% + 2rem);
}

Or you can use underscores _ instead of whitespaces:

Ref: Handling whitespace

<script src="https://cdn.tailwindcss.com"></script>
<div class="h-20 w-[calc(100%_-_10rem)] bg-yellow-200"></div>

We can use the theme variables as well:

h-[calc(100%-theme(space.24))]
Sign up to request clarification or add additional context in comments.

4 Comments

It is also possible to omit the whitespaces like so w-[calc(100%-10rem)]
Remember guys, without space!
If you want to add this to the tailwind config file, then you should use spaces instead of underscores when extending the theme.
It's much better to rely on the spacing rather than on the exact value. So h-[calc(100%-theme(space.N))] is much better. The second best option is h-[calc(100%-var(--spacing)*10)].
70

theme()

Use the theme() function to access your Tailwind config values using dot notation.

This can be a useful alternative to @apply when you want to reference a value from your theme configuration for only part of a declaration:

.content-container {
  height: calc(100vh - theme('spacing.7'));
}

5 Comments

This is the exact use case I was looking for. Not sure what 'spacing.7' is exactly, but thanks!
I think the spacing. is relevant to h- for me I use h-20 so spacing.20 worked for me
@JohnY Brother you should not put spaces in your class string. it is mentioned many times in this answer.
A bit late to the party but "spacing" is the unit in tailwind used for all padding, margin, gap, height, width, etc. In case other people reading this are wondering.
12

The documentation for Tailwind CSS has the section for arbitrary value https://tailwindcss.com/docs/adding-custom-styles#using-arbitrary-values.

The calc() function can be put as a arbitrary value.

For example, the class:

<div class="h-[calc(512px-3rem)]"></div>

Will be generated by Tailwind CSS as:

.h-\[calc\(512px-3rem\)\] {
  height: calc(512px - 3rem);
}

This code can be demonstrated here: https://play.tailwindcss.com/amqGV6rcZ8.


Mind that space can't be put inside a class name with arbitrary value, as such underscore character can be used instead: https://tailwindcss.com/docs/adding-custom-styles#handling-whitespace

Comments

3

go to config.js file in extend add: height: { '100vh-h-7': 'calc(100vh - 3rem)', }, and in your html you can use this class like below:

Content Container (100vh-h-7)

Comments

3

TLDR: Use utilities by @utility

/* 100vh - h-{number} */
@utility h-screen-minus-* {
  height: calc(100vh - var(--spacing) * --value(integer));
  height: calc(100vh - --value([length]));
}
/* 100dvh - h-{number} */
@utility h-dvh-minus-* {
  height: calc(100dvh - var(--spacing) * --value(integer));
  height: calc(100dvh - --value([length]));
}
/* 100lvh - h-{number} */
@utility h-lvh-minus-* {
  height: calc(100lvh - var(--spacing) * --value(integer));
  height: calc(100lvh - --value([length]));
}
/* 100svh - h-{number} */
@utility h-lvh-minus-* {
  height: calc(100svh - var(--spacing) * --value(integer));
  height: calc(100svh - --value([length]));
}
/* 100% - h-{number} */
@utility h-full-minus-* {
  height: calc(100% - var(--spacing) * --value(integer));
  height: calc(100% - --value([length]));
}

/* 100vw - w-{number} */
@utility w-screen-minus-* {
  width: calc(100vw - var(--spacing) * --value(integer));
  width: calc(100vw - --value([length]));
}
/* 100% - w-{number} */
@utility w-full-minus-* {
  width: calc(100% - var(--spacing) * --value(integer));
  width: calc(100% - --value([length]));
}

Avoid declaring many different custom class names

Declaring calculation-based classes one by one is not a great idea, as it results in a compiled CSS file filled with many unnecessary, single-use classes. Instead, we should focus on defining reusable utilities that can easily cover multiple use cases.

TailwindCSS v4

New utility: h-screen-minus-{number}

Sticking to the question, we subtract h-7 from 100vh (screen). We can call this utility h-screen-minus. The format h-screen-minus-{number} means we subtract {number} from 100vh. Like this:

In the example, instead of using 4 separate calculated classes, I used a single shared utility. This significantly improved my compiled CSS, avoiding the complexity of dealing with 4 different calculation-based class names, such as: h-\[calc\(100vh\-2rem\)\] Moreover, I didn't have to memorize the rem values; instead, I could use the spacing introduced in v4, ensuring consistent sizing.

<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@utility h-screen-minus-* {
  height: calc(100vh - var(--spacing) * --value(integer)); /* handle numbers e.g. h-screen-minus-12 */
  height: calc(100vh - --value([length])); /* handle arbitrary values e.g. h-screen-minus-[20px] */
}
</style>

<div class="flex text-white">
  <div class="h-screen w-30 bg-red-800">100vh</div>
  <div class="h-screen-minus-7 w-30 bg-red-700">100vh - (h-7)</div>
  <div class="h-screen-minus-14 w-30 bg-red-600">100vh - (h-14)</div>
  <div class="h-screen-minus-96 w-30 bg-red-500">100vh - (h-96)</div>
  <div class="h-screen-minus-[80px] w-30 bg-red-500">100vh - (h-[80px])</div>
</div>

New utility: w-screen-minus-{number}

This can also be applied to width, where 100vw - h-{number} would be, for example, w-screen-minus-{number}.

<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@utility w-screen-minus-* {
  width: calc(100vw - var(--spacing) * --value(integer)); /* handle numbers e.g. w-screen-minus-12 */
  width: calc(100vw - --value([length])); /* handle arbitrary values e.g. w-screen-minus-[20px] */
}
</style>

<div class="flex flex-col text-white">
  <div class="w-screen h-7 bg-red-800">100vw</div>
  <div class="w-screen-minus-7 h-7 bg-red-700">100vw - (w-7)</div>
  <div class="w-screen-minus-14 h-7 bg-red-600">100vw - (w-14)</div>
  <div class="w-screen-minus-96 h-7 bg-red-500">100vw - (w-96)</div>
  <div class="w-screen-minus-[80px] h-7 bg-red-500">100vw - (w-[80px])</div>
</div>

Comments

1

You can simply use this class h-[calc(100vh+1.75rem) hence h-7 is equal to 1.75rem

<div class="w-screen h-[calc(100vh+1.75rem)] bg-slate-400"></div>

Or in your global.css file

.content-container {
    @apply h-[calc(100vh+1.75rem)];
}

Comments

0

Since tailwind 4, I believe in most cases it's better not to add dynamic property for classes:

:class=`w-[calc(100%-${property})]`

If offset is not a CSS variable this will not work.

For that reason, they either need to be set, not dynamically though, as I mentioned before, but:

   const spacing = reactive({
        1: "w-[calc(100%-2rem)]",
        2: "w-[calc(100%-3rem)]",
        3: "w-[calc(100%-4rem)]",
    });

The other option is to calculate based on the reference CSS helper:

1>

class="w-[calc(100%-var(--offset))]" style="--offset: 2rem;".

2>

Global CSS:

:root {
  --offset: 2rem;
}

the in the template:

class="w-[calc(100%-var(--offset))]"

3>

:class="spacing[1]

1 Comment

There are still projects that use older versions of Tailwind, before v4. In those cases, I think the more dynamic insertion of values as partials to the existing class is more possible.
0
h-<number>
height: calc(var(--spacing) * <number>);
h-<fraction>
height: calc(<fraction> * 100%);

https://tailwindcss.com/docs/height

2 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
-1

I had the same problem, but with flexbox.

<div class="flex gap-6">
  <div class="basis-1/3">Test</div>
  <div class="basis-1/3">Test</div>
  <div class="basis-1/3">Test</div>
  <div class="basis-1/3">Test</div>
</div>

In this case the gap would not allow me to have 3 columns, so I needed to remove some spacing. Inside my tailwind.config.ts file, I extended the theme for flexBasis. Here is the full code:

flexBasis({ theme }) {
  const spacing = theme("spacing");
  const size = theme("size");

  // Filter percentage sizes and generate custom flex-basis values
  const percentageSizes = Object.keys(size).filter((key) => key.includes('/'));

  // Map over percentage sizes and spacing to generate CSS custom properties
  const flexBasisValues = percentageSizes.flatMap((sizeKey) =>
    Object.entries(spacing).map(([spacingKey, spacingValue]) => {
      const [numerator, denominator] = sizeKey.split('/').map(Number);
      const calcValue = `calc((100% - ${(denominator - 1)} * ${spacingValue}) / ${denominator} * ${numerator})`;
      return [`${sizeKey}-calc-${spacingKey}`, calcValue];
    })
  );
  return Object.fromEntries(flexBasisValues);
},

The end result made it so I can simply write:

<div class="flex gap-6">
  <div class="basis-1/3-calc-6">Test</div>
  <div class="basis-1/3-calc-6">Test</div>
  <div class="basis-1/3-calc-6">Test</div>
  <div class="basis-1/3-calc-6">Test</div>
</div>

Instead of writing this for each child:

basis-[calc((100%_-_2_*_theme(spacing.6))_/_3)]

Also my approach made it so I can easily change the gap size and update the children easily.

I believe this answer gives another approach that wasn't mentioned.

Comments

-2

Try this.

.content-container {
  height: calc(100vh - 1.75rem); /* Subtract the height of h-7, assuming 1rem = 16px */
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.