Patrik Krehák
Patrik Krehák

Reputation: 2683

Overlap ::after and ::before with text in CSS

Goal: Make nice effect of hovering buttons in pure CSS, which will use ::after and ::before pseudo-elements. Look at this jsFiddle example to see, what I want to reach.

Code: Button will have some styling, also an background-color, which is turned off in this example.

.button {
    display: inline-block;
    position: relative;
    height: 35px;
    line-height: 35px;
    padding: 0 15px;
    /*background-color: white;*/
    text-decoration: none;
    color: black;
}

Problem: I want to use background-color and when I enable it, then I can't see pseudo-elements. It is like that, because these pseudo-elements have z-index: -1;, which put them behind the background. When I change z-index to 0 or 1, then text is not visible.

What I can't do: I can't add new elements inside buttons (like spans), because this is one already running website and client decided to change the behavior of buttons, so here I am. There are tons of buttons in this website, so this is the reason, why I want to find solution with pseudo-elements, because trying to find every single button and change them would be inappropriate.

Upvotes: 1

Views: 6822

Answers (4)

Jerad Rutnam
Jerad Rutnam

Reputation: 1546

You can do something like,

HTML

<a href="#" class="button"></a>

CSS

body {
    background: #FF7272;
}
.button {
    display: inline-block;
    position: relative;
    height: 35px;
    line-height: 35px;
    padding: 0 15px;
    text-decoration: none;
    color: black;
    z-index: 0;
    background-color: white;
    width: 50px;
}
.button::before, .button::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
}
.button::after {
    content: "TEST";
    height: 50%;
    width: 72px;
    text-align: center;
    z-index: 2;
    line-height: 0.2;
    border-left: 4px solid red;
    border-right: 4px solid red;
    border-bottom: 4px solid red;
}
.button::before {
    height: 0%;
    background-color: red;
    transition: all 0.5s ease 0s;
    z-index: 1;
}
.button:hover::before {
    height: 100%;
}

Example: https://jsfiddle.net/LL0f7rwp/6/

Some values are hard coded, but hope you can get an idea out of it :)

Upvotes: 1

Pugazh
Pugazh

Reputation: 9561

It's because z-index: -1 and background-color: white will push your :before and :after elements beneath.

  1. Remove z-index: -1 from :after and :before and add to hover .button:hover::before
  2. Make the background-color: transparent while hovering. Updated fiddle.

body {
  background: #FF7272;
}
.button {
  display: inline-block;
  position: relative;
  height: 35px;
  line-height: 35px;
  padding: 0 15px;
  background-color: white;
  text-decoration: none;
  color: black;
}
.button::before,
.button::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
}
.button::after {
  height: 50%;
  border: 4px solid red;
  border-top: 0;
}
.button::before {
  height: 0%;
  background-color: red;
  transition: all 0.5s ease 0s;
}
.button:hover::before {
  height: 100%;
  z-index: -1;
}
.button:hover {
  background-color: transparent;
}
<a href="#" class="button">TEST</a>

Upvotes: 0

divy3993
divy3993

Reputation: 5810

If i understood you well, this is what you are looking for:

.button {
    display: inline-block;
    position: relative;
    height: 35px;
    line-height: 35px;
    padding: 0 15px;
    /*background-color: white;*/
    text-decoration: none;
    color: black;
	border:1px solid;
}
a.button:before {
    content: " ";
    display: block;
    z-index: -1;
    position: absolute;
    height: 0%;
    top: 0;
    right: 0;
    left: 0;
    background: #ddd;
	transition: height 0.2s ease;
}

a.button:hover:before {
	height:100%;
}
<a href="#" class="button">TEST</a>

Upvotes: 3

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324820

Consider an alternative method of doing the background colour transition thing.

As seen in this edited demo:

/* remove all references to .button::before */
.button {
    background-image: linear-gradient(to bottom,
        transparent, transparent 100%,
        red 100%, red);
    transition: background-image 0.5s ease 0s;
}
/* the "gradient" above has the practical result of being fully transparent,
   but it has been carefully crafted so that the transition gives the desired result */
.button:hover {
    background-image: linear-gradient(to bottom,
        transparent, transparent 0%,
        red 0%, red);
}

You can transition gadients, and in this case it is done stop-by-stop. The first and last stops don't change, but the middle two transition from 100% to 0%, essentially meaning that the cut-off point between transparent and red slides from the bottom to the top of the button, giving the effect you want.

You can now replace transparent with your desired background colour.

* You may need to remove the z-index:-1 from the ::after element to get the border effect back.

Upvotes: 2

Related Questions