4

I’m working on a grid layout using Tailwind CSS (v4.1).

Visit this play snippet
https://play.tailwindcss.com/cAvvS656Ts

Here’s a minimal example:

<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@utility border-line-1 {
  content: "";
  width: 100vw;
  height: 2px;
  background-color: red;
  position: absolute;
  bottom: 0;
  left: 0;
}
</style>

<body class="bg-gray-800">
  <section class=" h-[100vh] w-full bg-gray-900 p-4 text-white">
    <div class=" grid grid-cols-4 grid-rows-6 gap-5">
      <div class="row-span-6 border border-white">A</div>
      <div class="relative col-span-2 border border-white after:border-line-1">B</div>
      <div class="row-span-6 border border-white">C</div>
      <div class="row-span-4 border border-white">D</div>
      <div class="row-span-4 border border-white">E</div>
      <div class="col-span-2 border border-white">F</div>
    </div>
  </section>
</body>

What I want

  • The red line should start from the beginning of section A (so basically from the very left edge of the grid container).

  • It should span the entire width (A → B → C).

  • It should sit exactly at the bottom of B.

What happens now

Since the pseudo-element is inside B, it only positions relative to B. If I hack it with left:-180px, it looks close to what I want — but that’s not responsive or correct.

Question

How can I properly make this red line span the full width of the grid container but align with the bottom of B without hardcoding offsets?

Note

This is purely a CSS positioning issue — I’m just using Tailwind classes to generate the CSS, so I added the tailwind-css tag as well.

5
  • Must it be a pseudo element of B, or can it be another element as long as it achieves the same required visual effect? Or otherwise, can HTML structure be altered? Commented Sep 13 at 6:53
  • @Wongjn The reason I’m trying to use a ::after pseudo-element is because in my layout I sometimes use the same technique to place vertical divider lines and sometimes horizontal lines. So if I can make this work with ::after, it keeps the approach consistent and reusable. Commented Sep 13 at 7:00
  • @Wongjn If you check this image: awesomescreenshot.com/image/… , you’ll see the effect that I want in the bottom menus. Right now, each section is separated by a kind of square/box divider. That’s the “active” separator I’m using, but I’m not satisfied with how it’s implemented — it feels more like a workaround than the correct way. What I actually need is the proper CSS way to create those dividers. If necessary, I can share the full HTML/CSS code for the image so the issue is clearer. Commented Sep 13 at 7:09
  • @Wongjn Ultimately, I need to find the proper solution to create this visual effect. I don’t mind whether it requires altering the HTML or using CSS — either way is fine. The important part is that I should be able to easily place horizontal or vertical lines to achieve the kind of visual effect shown in the image I shared above. Commented Sep 13 at 7:22
  • @Wongjn, this layout design I want canva.com/design/DAGy1GAWyZY/EsgRj9awDyo0-R_c-tGDVA/… Commented Sep 13 at 7:37

4 Answers 4

3

A perfect use case for anchor positioning even if the support is still not good

section:after {
  content: "";
  position: absolute;
  height: 2px;
  background-color: red;
  inset: auto anchor(--C right) anchor(--B bottom) anchor(--A left);
}
.A { anchor-name: --A}
.B { anchor-name: --B}
.C { anchor-name: --C}
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>

<body class="bg-gray-800">
  <section class=" h-[100vh] w-full bg-gray-900 p-4 text-white">
    <div class=" grid grid-cols-4 grid-rows-6 gap-5">
      <div class="row-span-6 border border-white A">A</div>
      <div class="relative col-span-2 border border-white B">B</div>
      <div class="row-span-6 border border-white C">C</div>
      <div class="row-span-4 border border-white">D</div>
      <div class="row-span-4 border border-white">E</div>
      <div class="col-span-2 border border-white">F</div>
    </div>
  </section>
</body>

Sign up to request clarification or add additional context in comments.

Comments

1

Temani Afif's answer makes great use of the new anchors. However, as of today they are still classified as Limited, meaning they're not available in every browser and they raise the minimum browser version requirement for your project. Let's compare this with TailwindCSS v4's minimum requirement to see where and by how much it increases it:

Tailwind CSS v4 (without anchor positioning) with anchor positioning
Chrome 111 Chrome 125 (+)
Safari 16.4 Safari 26.0 (+++)
Firefox 128 Important: not supported (ERR)

So currently, Chrome adopted it early, Safari quite late, and Firefox still hasn't implemented it to this day. With that in mind, I recommend using anchor positioning with great caution.

Temani's answer is pretty great for CSS. Let's see how anchor positioning can be implemented manually into the TailwindCSS utility system:

<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@utility line-on-* {  
  &::after {
    content: "";
    position: absolute;
    height: 2px;
    background-color: var(--color-red-500);
    bottom: anchor(--value([*]) bottom);
  }
}

@utility line-from-* {  
  &::after {
    left: anchor(--value([*]) left);
  }
}

@utility line-to-* {  
  &::after {
    right: anchor(--value([*]) right);
  }
}
</style>

<body class="bg-gray-800">
  <section class="h-[100vh] w-full bg-gray-900 p-4 text-white">
    <div class="grid grid-cols-4 grid-rows-6 gap-5">
      <div class="row-span-6 border border-white [anchor-name:--A]">A</div>
      <div class="col-span-2 border border-white [anchor-name:--B]">B</div>
      <div class="row-span-6 border border-white [anchor-name:--C]">C</div>
      <div class="row-span-4 border border-white [anchor-name:--D]">D</div>
      <div class="row-span-4 border border-white [anchor-name:--E]">E</div>
      <div class="col-span-2 border border-white [anchor-name:--F]">F</div>
    </div>

    <span class="line-on-[--B] line-from-[--A] line-to-[--C]"></span>
    <span class="line-on-[--D] line-from-[--A] line-to-[--C]"></span>
    <span class="line-on-[--A] line-from-[--A] line-to-[--C]"></span>
  </section>
</body>

3 Comments

Thanks for creating this Tailwind version for anchors. I do have an opinion that I recently shared in a GitHub discussion on Tailwind. It would be great if you could check it out—I’m really interested in hearing your thoughts! github.com/tailwindlabs/tailwindcss/discussions/18925
Not working on Firefox :)
1

In short, what you want isn't possible with CSS. You would need to align the ::after both to the bottom of its direct parent and to the left and right edges of the .grid. Absolute positioning can only align to one parent at a time - the nearest relative parent.

An absolutely positioned element can only align itself relative to its parent and cannot determine its position based on the left and right edges of a larger ancestor. Here's an example where I center the line relative to its parent:

<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@utility border-line-1 {
  height: 2px;
  width: 50%;
  background-color: red;
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
}
</style>

<body class="bg-gray-800">
  <section class="h-[100vh] w-full bg-gray-900 p-4 text-white">
    <div class="grid grid-cols-4 grid-rows-6 gap-5">
      <div class="relative row-span-6 border border-white after:border-line-1">A</div>
      <div class="relative col-span-2 border border-white after:border-line-1">B</div>
      <div class="row-span-6 border border-white">C</div>
      <div class="relative row-span-4 border border-white after:border-line-1">D</div>
      <div class="row-span-4 border border-white">E</div>
      <div class="col-span-2 border border-white">F</div>
    </div>
  </section>
</body>

Right now, the only way to be sure the border-line is long enough is with a very ugly solution, and you can prevent overflow in the .grid parent:

<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@utility border-line-1 {
  height: 2px;
  width: 100%;
  padding-inline: 100cqw;
  background-color: red;
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
}
</style>

<body class="bg-gray-800">
  <section class="h-[100vh] w-full bg-gray-900 p-4 text-white">
    <div class="grid grid-cols-4 grid-rows-6 gap-5 overflow-hidden">
      <div class="relative row-span-6 border border-white after:border-line-1">A</div>
      <div class="relative col-span-2 border border-white after:border-line-1">B</div>
      <div class="row-span-6 border border-white">C</div>
      <div class="relative row-span-4 border border-white after:border-line-1">D</div>
      <div class="row-span-4 border border-white">E</div>
      <div class="col-span-2 border border-white">F</div>
    </div>
  </section>
</body>

Or another ugly solution:

<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@utility border-line-1 {
  height: 2px;
  background-color: red;
  position: absolute;
  bottom: 0;
  left: -100cqw;
  right: -100cqw;
}
</style>

<body class="bg-gray-800">
  <section class="h-[100vh] w-full bg-gray-900 p-4 text-white">
    <div class="grid grid-cols-4 grid-rows-6 gap-5 overflow-hidden">
      <div class="relative row-span-6 border border-white after:border-line-1">A</div>
      <div class="relative col-span-2 border border-white after:border-line-1">B</div>
      <div class="row-span-6 border border-white">C</div>
      <div class="relative row-span-4 border border-white after:border-line-1">D</div>
      <div class="row-span-4 border border-white">E</div>
      <div class="col-span-2 border border-white">F</div>
    </div>
  </section>
</body>

2 Comments

The second piece of code you provided might work, but I’m still looking for the most elegant, purely dynamic solution. Once I find it, I’ll definitely share it here. Thank you for your mentorship and valuable time — I am really thankful to you.
Working on Chrome, Edge, Firefox and Safari. :)
1

If we drop the after: variant, we could write a utility directly on the parent element to make it relative, and then set up the before and after pseudo-elements within it.

<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@utility border-line-* {  
  position: relative;
  
  &::before, &::after {
    content: "";
    position: absolute;
    left: -100vw;
    height: calc(--value(integer) * 2px);
    height: --value([length]);
    width: 200vw;
  }
  
  /* Top line */
  /*
  &::before {
    top: 0;
    background-color: var(--color-blue-500);
  }
  */
  
  /* Bottom line */
  &::after {
    bottom: 0;
    background-color: var(--color-red-500);
  }
}
</style>

<body class="bg-gray-800 overflow-x-hidden">
  <section class="h-[100vh] w-full bg-gray-900 p-4 text-white">
    <div class="grid grid-cols-4 grid-rows-6 gap-5">
      <div class="row-span-6 border border-white border-line-1">A</div>
      <div class="col-span-2 border border-white border-line-1">B</div>
      <div class="row-span-6 border border-white">C</div>
      <div class="row-span-4 border border-white border-line-1">D</div>
      <div class="row-span-4 border border-white">E</div>
      <div class="col-span-2 border border-white">F</div>
    </div>
  </section>
</body>

The overflow still remains, I just made it a bit more consistent, since it always has to be placed in a pseudo-element.

4 Comments

Look at this: play.tailwindcss.com/DQJTgWsY6K . I can easily achieve the effect with that code, but I want the same effect for the OP’s code.
This exact approach is used for the Tailwind sponsor section located on the home page of the Tailwind official website
Working on Chrome, Edge, Firefox and Safari. :)

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.