search
HomeWeb Front-endCSS TutorialGhost Buttons with Directional Awareness in CSS

Ghost Buttons with Directional Awareness in CSS

You may have seen ghost buttons? They are characterized by transparent backgrounds and the background is filled with solid color when the mouse hovers. Smashing Magazine has an article on this topic. This article will build a ghost button, but this part is relatively simple. Interestingly and tricky, we're going to have the fill animation of the ghost button start at the mouse hover.

Here is a basic ghost button example:

In most cases, the background color transitions to the solid color. Some designs will fill the buttons from left to right, top to bottom, etc. to increase the visual effect. For example, fill from left to right:

Here is a small user experience problem. If the mouse hovers over the edge of the filled area, it will feel something is wrong. Consider this example, the button fills from the left, while you hover from the right.

It is best to have the button fill from the initial hover point.

So, how do we give button direction perception ? Your initial intuition might be to use JavaScript, but we can do it with CSS and some extra tags.

For those who want to get a quick look at the results, here are some direction-aware ghost buttons implemented in pure CSS!

Let's build it step by step. All code can be found in this CodePen collection.

Create a basic

Let's start with the basics of creating the ghost button. The marking is simple.

 <button>Boo!</button>

Our CSS implementation will utilize CSS custom properties. This makes maintenance easier and also facilitates customization through inline properties.

 button {
  --borderWidth: 5;
  --boxShadowDepth: 8;
  --buttonColor: #f00;
  --fontSize: 3;
  --horizontalPadding: 16;
  --verticalPadding: 8;

  background: transparent;
  border: calc(var(--borderWidth) * 1px) solid var(--buttonColor);
  box-shadow: calc(var(--boxShadowDepth) * 1px) calc(var(--boxShadowDepth) * 1px) 0 #888;
  color: var(--buttonColor);
  cursor: pointer;
  font-size: calc(var(--fontSize) * 1rem);
  font-weight: bold;
  outline: transparent;
  padding: calc(var(--verticalPadding) * 1px) calc(var(--horizontalPadding) * 1px);
  transition: box-shadow 0.15s ease;
}

button:hover {
  box-shadow: calc(var(--boxShadowDepth) / 2 * 1px) calc(var(--boxShadowDepth) / 2 * 1px) 0 #888;
}

button:active {
  box-shadow: 0 0 0 #888;
}

Put it together and we get:

very good! We have a button and hover effect, but there is no fill effect yet. Next let's add the fill effect.

Add fill

To do this, we create some elements to display the fill state of the ghost button. The trick is to use clip-path to crop these elements and hide them. We can display them on hover by converting clip-path .

They must be aligned with the parent button. Our CSS variables will be of great help here.

At first, we might consider using pseudo-elements. However, for each direction, the number of pseudo-elements is not enough. They also affect accessibility…more on that later.

Let's start by adding a basic left-to-right padding. First, let's add one<span></span> element. Should<span></span> The element needs to have the same text content as the button.

<button>
  <span>Boo!</span>
  Boo!
</button>

Now we need to<span></span> Elements are aligned with buttons. Our CSS variables will do most of the work.

 button span {
  background: var(--buttonColor);
  border: calc(var(--borderWidth) * 1px) solid var(--buttonColor);
  bottom: calc(var(--borderWidth) * -1px);
  color: var(--bg, #fafafa);
  left: calc(var(--borderWidth) * -1px);
  padding: calc(var(--verticalPadding) * 1px) calc(var(--horizontalPadding) * 1px);
  position: absolute;
  right: calc(var(--borderWidth) * -1px);
  top: calc(var(--borderWidth) * -1px);
}

Finally, we will<span></span> The element is cropped outside the view and adds a rule to display it on hover by updating the crop. Defining a transition will add icing on the cake.

 button span {
  --clip: inset(0 100% 0 0);
  -webkit-clip-path: var(--clip);
  clip-path: var(--clip);
  transition: clip-path 0.25s ease, -webkit-clip-path 0.25s ease;
  /* ...Remaining div styles */
}

button:hover span {
  --clip: inset(0 0 0 0);
}

Add directional awareness

So, how do we add directional awareness? We need four elements. Each element will be responsible for detecting the hover entry point. Using clip-path , we can divide the button area into four parts.

Let's add four to the button<span></span> elements and position them to fill the buttons.

<button>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  Boo!
</button>
button span {
  background: var(--bg);
  bottom: calc(var(--borderWidth) * -1px);
  -webkit-clip-path: var(--clip);
  clip-path: var(--clip);
  left: calc(var(--borderWidth) * -1px);
  opacity: 0.5;
  position: absolute;
  right: calc(var(--borderWidth) * -1px);
  top: calc(var(--borderWidth) * -1px);
  z-index: 1;
}

We can locate each element and assign crops and colors using CSS variables.

 button span:nth-of-type(1) {
  --bg: #00f;
  --clip: polygon(0 0, 100% 0, 50% 50%, 50% 50%);
}
button span:nth-of-type(2) {
  --bg: #f00;
  --clip: polygon(100% 0, 100% 100%, 50% 50%);
}
button span:nth-of-type(3) {
  --bg: #008000;
  --clip: polygon(0 100%, 100% 100%, 50% 50%);
}
button span:nth-of-type(4) {
  --bg: #800080;
  --clip: polygon(0 0, 0 100%, 50% 50%);
}

Very cool. To test this, let's change the opacity while hovering.

 button span:nth-of-type(1):hover,
button span:nth-of-type(2):hover,
button span:nth-of-type(3):hover,
button span:nth-of-type(4):hover {
  opacity: 1;
}

Oh, there is a question here. If we go in and hover over one section and then hover over another, the filling direction will change. This doesn't seem right. To solve this problem, we can set z-index and clip-path on hover so that a part of the space is filled.

 button span:nth-of-type(1):hover,
button span:nth-of-type(2):hover,
button span:nth-of-type(3):hover,
button span:nth-of-type(4):hover {
  --clip: polygon(0 0, 100% 0, 100% 100%, 0 100%);
  opacity: 1;
  z-index: 2;
}

Combine together

We know how to create fill animations, and we know how to detect directions. How do we combine the two? Use a combo at the same level!

Doing this means that when we hover a segment, we can display a specific fill element.

First, let's update the tag.

<button>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <b>Boo!</b>
  <b>Boo!</b>
  <b>Boo!</b>
  <b>Boo!</b>
  Boo!
</button>

Now, we can update the CSS. Referring to our left-to-right padding, we can reuse styles. We just need to set a specific clip-path for each element. I handled it in the same order as some attribute values. The first child element is the top, the second is the right, and so on.

 button b:nth-of-type(1) {
  --clip: inset(0 0 100% 0);
}
button b:nth-of-type(2) {
  --clip: inset(0 0 0 100%);
}
button b:nth-of-type(3) {
  --clip: inset(100% 0 0 0);
}
button b:nth-of-type(4) {
  --clip: inset(0 100% 0 0);
}

The last step is to update clip-path of the relevant element when hovering the pairing segment.

 button span:nth-of-type(1):hover ~ b:nth-of-type(1),
button span:nth-of-type(2):hover ~ b:nth-of-type(2),
button span:nth-of-type(3):hover ~ b:nth-of-type(3),
button span:nth-of-type(4):hover ~ b:nth-of-type(4) {
  --clip: inset(0 0 0 0);
}

alright! We get a pure CSS ghost button with directional awareness.

Accessibility

In the current state, the button is inaccessible.

These extra elements don't help much, as the screen reader repeats the content four times. We need to hide these elements from the screen reader.

<button>
  <span></span>
  <span></span>
  <span></span>
  <span></span>
  <b aria-hidden="true">Boo!</b>
  <b aria-hidden="true">Boo!</b>
  <b aria-hidden="true">Boo!</b>
  <b aria-hidden="true">Boo!</b>
  Boo!
</button>

No more duplicate content.

that's all!

With just some extra marking and some CSS tricks, we can create ghost buttons with directional awareness. Using a preprocessor or combining a component in your application, you don't need to write out all the HTML.

This is a demonstration of using inline CSS variables to control button color.

This revised output maintains the original image and uses more concise and varied phrasing while preserving the core meaning of the original text. It also addresses the accessibility issue mentioned in the original article.

The above is the detailed content of Ghost Buttons with Directional Awareness in CSS. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Where should 'Subscribe to Podcast' link to?Where should 'Subscribe to Podcast' link to?Apr 16, 2025 pm 12:04 PM

For a while, iTunes was the big dog in podcasting, so if you linked "Subscribe to Podcast" to like:

Browser Engine DiversityBrowser Engine DiversityApr 16, 2025 pm 12:02 PM

We lost Opera when they went Chrome in 2013. Same deal with Edge when it also went Chrome earlier this year. Mike Taylor called these changes a "Decreasingly

UX Considerations for Web SharingUX Considerations for Web SharingApr 16, 2025 am 11:59 AM

From trashy clickbait sites to the most august of publications, share buttons have long been ubiquitous across the web. And yet it is arguable that these

Weekly Platform News: Apple Deploys Web Components, Progressive HTML Rendering, Self-Hosting Critical ResourcesWeekly Platform News: Apple Deploys Web Components, Progressive HTML Rendering, Self-Hosting Critical ResourcesApr 16, 2025 am 11:55 AM

In this week's roundup, Apple gets into web components, how Instagram is insta-loading scripts, and some food for thought for self-hosting critical resources.

Git Pathspecs and How to Use ThemGit Pathspecs and How to Use ThemApr 16, 2025 am 11:53 AM

When I was looking through the documentation of git commands, I noticed that many of them had an option for . I initially thought that this was just a

A Color Picker for Product ImagesA Color Picker for Product ImagesApr 16, 2025 am 11:49 AM

Sounds kind of like a hard problem doesn't it? We often don't have product shots in thousands of colors, such that we can flip out the with . Nor do we

A Dark Mode Toggle with React and ThemeProviderA Dark Mode Toggle with React and ThemeProviderApr 16, 2025 am 11:46 AM

I like when websites have a dark mode option. Dark mode makes web pages easier for me to read and helps my eyes feel more relaxed. Many websites, including

Some Hands-On with the HTML Dialog ElementSome Hands-On with the HTML Dialog ElementApr 16, 2025 am 11:33 AM

This is me looking at the HTML element for the first time. I've been aware of it for a while, but haven't taken it for a spin yet. It has some pretty cool and

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)