A while ago I came across a pagination style that looked especially sharp: angled edges, compact labels, and a shape that felt more dynamic than a plain rectangle. I ended up using the same idea in a blog pagination bar, and the result looked like this:

You can picture the effect as a row of small slanted tags. The interesting part is that this kind of shape can be built in CSS without any images at all. There are two practical approaches: one relies on border, and the other uses transform.
Method 1: Constructing the shape with border
The first technique uses the classic CSS triangle trick. Once you can create a triangle, a parallelogram is just a rectangle joined with two triangles, one on each side.
Why does border produce a triangle in the first place? The basic idea is easiest to understand by looking at how borders behave when an element shrinks down to no intrinsic size:

There are really only two conditions required:
- The element itself must have
width: 0andheight: 0. - The unwanted sides need to be hidden by setting their
border-colorto transparent.
Using the same principle, you can create other shapes too, including trapezoids. Here are the three examples shown above:
#first {
width: 20px;
height: 20px;
border-width: 10px;
border-style: solid;
border-color: red green blue brown;
}
#second {
width: 0;
height: 0;
border-width: 10px;
border-style: solid;
border-color: red green blue brown;
}
#third {
width: 0;
height: 0;
border-width: 10px;
border-style: solid;
border-color: red transparent transparent transparent;
}
Once the triangle itself is clear, the next step is assembling a parallelogram. With the border approach, the shape is made from three pieces:
- a left triangle
- a center rectangle
- a right triangle
Creating three separate elements every time would be cumbersome, so pseudo-elements are a much cleaner option here. :before and :after can be used for the two side triangles, while the main element provides the rectangular middle.
The intended result looks like this:

Because the triangles and the center block need to align perfectly, several properties have to stay in sync. This is the kind of CSS that becomes easier to manage in a preprocessor such as Less, Sass, or Stylus. Here is the SCSS version:
//三角形的宽高
$height: 24px;
$width: 12px;
//对平行四边形三部分的颜色进行赋值
@mixin parallelogram-color($color) {
background: $color;
&:before { border-color: transparent $color $color transparent; }
&:after { border-color: $color transparent transparent $color; }
}
//单个三角形的样式
@mixin triangle() {
content: '';
display: block;
width: 0;
height: 0;
position: absolute;
border-style: solid;
border-width: $height/2 $width/2;
top: 0;
}
//平行四边形的样式
.para {
display: inline-block;
position: relative;
padding: 0 10px;
height: $height;
line-height: $height;
margin-left: $width;
color: #fff;
&:after {
@include triangle();
right: -$width;
}
&:before {
@include triangle();
left: -$width;
}
@include parallelogram-color(red);
}
One thing to watch out for: if the slope implied by $height and $width is too steep or too shallow, the edges may render with visible jaggedness. It is worth testing a few size combinations to see which proportions look best in actual browsers.
Method 2: Using transform and skew
The second approach is much simpler conceptually. Instead of piecing together triangles and rectangles, you start with a normal box and skew it into a parallelogram.
That effect can even be used for an outlined shape rather than a filled one, which is something the first method does not handle as naturally. A basic version looks like this:

The core of it is transform: skew(...):
<style>
.city {
display: inline-block;
padding: 5px 20px;
border: 1px solid #44a5fc;
color: #333;
transform: skew(-20deg);
}
</style>
<div class="city">上海</div>
This does create the parallelogram shape, but it also skews the text inside it:

That obviously is not the final result we want. The fix is to wrap the text in an inner element and apply the opposite skew to cancel out the distortion:

Here is the full version:
<style>
.city {
display: inline-block;
padding: 5px 20px;
border: 1px solid #44a5fc;
color: #333;
transform: skew(-20deg);
}
.city div {
transform: skew(20deg);
}
</style>
<div class="city">
<div>上海</div>
</div>
Choosing between the two
Both methods work, but they serve slightly different needs.
The border technique is great when you want to synthesize shapes such as triangles and trapezoid-like tags, then combine them into a filled parallelogram. It is flexible, but it takes more code and can be more finicky to maintain.
The transform method is shorter and easier to understand. For most simple parallelogram labels, it is the more straightforward choice. Its limitation is that it does not help much when you need a shape like the trapezoidal pagination style mentioned earlier.
A rendering issue worth knowing about
There is one practical caveat with border-based triangles: browser rendering can become inconsistent when the page is zoomed.
In testing, white seams could appear in the pagination shape under browser scaling. For example:
- Safari 8 showed the issue at 150% zoom.
- Chrome 45 showed it at 125% zoom.
The screenshots below illustrate the problem:


This exposes a real difference in how browsers render Border Triangle shapes under zoom. The behavior is not fully consistent across engines, and no reliable fix was found in this case. Because of that, the pagination bar was eventually rebuilt with the second method using transform instead.