DEV Community

Roland Taylor
Roland Taylor

Posted on

Creating Curtains With CSS

Hey y'all!

In this tutorial, I will show you a method for creating a "curtain" with CSS!

Demo:

Example gif

Method: Using ::Before and ::After:

For this method, I will use the pseudo-elements ::before and ::after to create my curtain. NB: For the sake of keeping things simple, I have only minimally styled them.

Let's start with the HTML code:

We'll create a pair of div elements, one with the class curtain-0 and the other with the class curtain-1. We'll examine these classes shortly.

<div class="curtain-0">
  Curtain content.
</div>
<div class="curtain-1">
  <button class="content">
    Curtain content.
  </button>
</div> 
Enter fullscreen mode Exit fullscreen mode

Note:
You need nothing more than a single block-level element, but I've included a button in the second example to show you that the curtains can actually hide other elements.

This is important to note; because hiding an element behind another is bad for accessibility. This is purely a proof of concept situation, and not recommended in practice, unless the curtains are activated by an event, and subsequently removed.


Now for the CSS

Just for the sake of clarity, I'll include the code I used for the body of this demo (source code will be posted at the end of this tutorial).

Styling the page:

/*I've grouped these together, since they
share the same styles, to avoid duplication*/
body, body > div {
  align-items: center;
  display: flex;
  justify-content: center;
}

/*We need to add a height to the body
so that it can center the content as we'd like*/
body {
  margin: 0;
  height: 100vh;
}
Enter fullscreen mode Exit fullscreen mode

Styling the containers:

On the container which will host our curtains, we need to use position: relative, so that any children positioned absolutely, are positioned in relation to their parent.

Technically, this is the only property:value pair you need, but I decided to use some additional styling for the purposes of this tutorial, so that you can more easily see the containers.

/*The following uses a 'wildcard' selector*/
[class*=curtain] {
  position: relative;
  border: 1px solid red;
  height: 100px;
  margin: 5vh;
  padding: 5vw;
}
Enter fullscreen mode Exit fullscreen mode

Note: For more about wildcard selectors, see here. With that out of the way, let's look at the code that does the heavy lifting.


The curtains:

To draw the curtains, we will make use of the pseudo-elements, ::before ::after. Now, I will warn you: CSS is rather involved, so while I've tried to keep the code as simplified as possible, there's still a lot to cover.

[class*=curtain]::after,
[class*=curtain]::before {
  content: '';
  background-color: green;
  position: absolute;
  transition-duration: 0.5s;
}
Enter fullscreen mode Exit fullscreen mode

To save space and simplify the code, I've joined the two definitions into one. Each one is "positioned" absolutely, but we will cover their actual positions separately.

You'll notice that I've included an empty content: property. This is necessary for these pseudo-elements to appear. Without it, they won't work. You could, if you like, include text of your own, but it won't look very good without additional styling.

The transition-duration property was included so that our transitions can be smooth, rather than instantaneous. It would kind of defeat the purpose if our curtains weren't animated!

Creating the halves:

For the left and right halves, we need:

.curtain-0::after,
.curtain-0::before {
  height: 100%;
  width: 50%;
}
Enter fullscreen mode Exit fullscreen mode

For the top and bottom halves, we need:


.curtain-1::after,
.curtain-1::before {
  height: 50%;
  width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

Establishing the separate styles for each half:

/*Left half*/
.curtain-0::before {
  left: 0;
  transform-origin: left;
}

/*Right half*/
.curtain-0::after {
  right: 0;
  transform-origin: right;
}

/*Bottom half*/
.curtain-1::after {
  bottom: 0;
  transform-origin: bottom;
}

/*Top half*/
.curtain-1::before {
  top: 0;
  transform-origin: top;
}
Enter fullscreen mode Exit fullscreen mode

Animating on hover:

To actually achieve the curtain effect, we will use a pseudo-class, in this case :hover.

I've grouped the two pseudo-elements together for changing their opacity, since this remains the same for both.

[class*=curtain]:hover:after,
[class*=curtain]:hover:before {
  opacity: 0;
}

Enter fullscreen mode Exit fullscreen mode

For the top and bottom halves:

.curtain-1:hover:after,
.curtain-1:hover:before {
  transform: scaleY(0);
}
Enter fullscreen mode Exit fullscreen mode

For the left and right halves:

.curtain-0:hover:after,
.curtain-0:hover:before {
  transform: scaleX(0);
}
Enter fullscreen mode Exit fullscreen mode

That's all for now!

There are other methods for achieving this effect, using the same pseudo-elements, or using multiple elements. I may cover these in follow-up tutorials, but for now, you can play with this method and let see your results! I'd be quite interested to see what others come up with!


Source Code: https://codepen.io/rolandixor/pen/qBjKxPd

Top comments (0)