Creating Curtains With CSS
Tags: css, design, webdev, html
Published: 2021-09-21 19:18:12

Hey y'all!

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

## Demo:
![Example gif](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hcz6yngkwuym16vmocye.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.

```html
<div class="curtain-0">
  Curtain content.
</div>
<div class="curtain-1">
  <button class="content">
    Curtain content.
  </button>
</div> 
```

---

**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:

```css
/*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;
}
```

#### 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.

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

---
**Note:** *For more about wildcard selectors, see [here](https://www.geeksforgeeks.org/wildcard-selectors-and-in-css-for-classes/). 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. 

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

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:

```css
.curtain-0::after,
.curtain-0::before {
  height: 100%;
  width: 50%;
}
```

For the top and bottom halves, we need:
```css

.curtain-1::after,
.curtain-1::before {
  height: 50%;
  width: 100%;
}
```

#### Establishing the separate styles for each half:

```css
/*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;
}
```

####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.

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

```

#### For the top and bottom halves:
```css
.curtain-1:hover:after,
.curtain-1:hover:before {
  transform: scaleY(0);
}
```

#### For the left and right halves:
```css
.curtain-0:hover:after,
.curtain-0:hover:before {
  transform: scaleX(0);
}
```

##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](https://codepen.io/rolandixor/pen/qBjKxPd)