CSS skew() Function

The CSS skew() function slants an element along the horizontal and vertical axes without changing its original layout dimensions.

It is used with the transform property to create angled shapes, slanted text, and visual effects. The function accepts one or two angle values, allowing horizontal skewing, vertical skewing, or both at the same time.

Syntax

transform: skew(ax);
transform: skew(ax, ay);

The skew() function accepts one required angle and one optional angle.

Examples:

transform: skew(15deg);
transform: skew(15deg, 0deg);
transform: skew(0deg, 15deg);
transform: skew(15deg, 10deg);
transform: skew(-15deg, -10deg);
transform: skew(0.05turn, 10deg);

The first argument controls horizontal skewing. The second controls vertical skewing.

If the second argument is omitted, it defaults to 0deg.

For example, these declarations produce the same transformation:

transform: skew(20deg);
transform: skew(20deg, 0deg);
transform: skewX(20deg);

The skew() function is a value of the CSS transform property. There is no separate CSS skew property.

Parameters

The skew() function accepts two angle parameters, with the second being optional.

Parameter Description
ax Required. The angle used to skew the element along the horizontal (X) axis.
ay Optional. The angle used to skew the element along the vertical (Y) axis. Defaults to 0deg.

Both parameters accept CSS angle values, including deg, rad, grad, and turn.

A unitless zero is also permitted:

transform: skew(0);
transform: skew(0, 15deg);
transform: skew(15deg, 0);

Nonzero angles must include a valid angle unit.

For example, skew(15) is invalid because 15 does not specify an angle unit.

The function returns a CSS <transform-function> value rather than a number or length.

How It Works

The skew() function changes the apparent shape of an element by shifting its points horizontally or vertically.

Unlike rotate(), which turns the entire element, skew() distorts its shape.

For example:

.box {
  transform: skew(20deg, 0deg);
}

The top and bottom edges remain horizontal, while the vertical edges become slanted.

With vertical skewing:

.box {
  transform: skew(0deg, 20deg);
}

The left and right edges remain vertical, while the horizontal edges become slanted.

When both angles are supplied, both sets of edges can become slanted.

The original element retains its layout space. The transformation changes its visual appearance without causing surrounding elements to move automatically.

The default transformation origin is the center of the element.

Angle Values

The skew() function supports the standard CSS angle units.

Unit Description Example
deg Degrees skew(15deg)
rad Radians skew(0.25rad)
grad Gradians skew(20grad)
turn Turns skew(0.05turn)

Positive Angles

A positive horizontal skew shifts points farther down the element toward the right, relative to points above them.

transform: skew(20deg, 0deg);

A positive vertical skew shifts points farther to the right downward, relative to points to their left.

transform: skew(0deg, 20deg);

Negative Angles

Negative angles reverse the direction of the corresponding skew.

transform: skew(-20deg, 0deg);
transform: skew(0deg, -20deg);

Zero Angles

When both angles are zero, no skewing occurs.

transform: skew(0deg, 0deg);

Although the element appears unchanged, a non-none transform still has effects such as creating a stacking context.

Avoid angles near 90 degrees or 270 degrees, where the tangent used by the transformation becomes extremely large or undefined.

Horizontal Skewing

Horizontal skewing changes the apparent angle of an element's vertical edges.

For example:

.box {
  transform: skew(20deg);
}

Because the second angle is omitted, the vertical skew is zero.

The following declarations are equivalent:

transform: skew(20deg);
transform: skew(20deg, 0deg);
transform: skewX(20deg);

A negative horizontal skew reverses the direction:

.box {
  transform: skew(-20deg);
}

Horizontal skewing is useful for angled panels, banners, and decorative shapes.

Vertical Skewing

Vertical skewing changes the apparent angle of an element's horizontal edges.

For example:

.box {
  transform: skew(0deg, 15deg);
}

The first angle is zero, so the element is skewed only along the Y axis.

The following declarations are equivalent:

transform: skew(0deg, 15deg);
transform: skewY(15deg);

Using a negative angle reverses the direction:

.box {
  transform: skew(0deg, -15deg);
}

Vertical skewing can create angled top and bottom edges without rotating the entire element.

Skewing Both Axes

Providing two nonzero angles applies horizontal and vertical skewing in a single transformation.

For example:

.box {
  transform: skew(15deg, 10deg);
}

The first angle skews the element horizontally by 15 degrees, while the second skews it vertically by 10 degrees.

Both angles can be positive, negative, or a combination:

transform: skew(15deg, 10deg);
transform: skew(-15deg, 10deg);
transform: skew(15deg, -10deg);
transform: skew(-15deg, -10deg);

The resulting shape depends on both values.

Using both axes can create a more complex distortion than skewing in only one direction.

For predictable results, begin with small angles and increase them gradually.

Transform Origin

The transform-origin property determines the point around which a transformation is applied.

By default, an HTML element transforms around its center:

.box {
  transform-origin: center;
  transform: skew(20deg);
}

The origin can be changed to an edge or corner.

For example:

.box {
  transform-origin: left center;
  transform: skew(20deg);
}

This uses the midpoint of the left edge as the transformation origin.

Other examples include:

transform-origin: top left;
transform-origin: top center;
transform-origin: center;
transform-origin: bottom right;
transform-origin: 25% 75%;

Changing the origin affects how the element appears to move during skewing, even when the skew angles remain the same.

This is useful when an angled element needs to stay visually aligned with a particular edge or corner.

skew() vs. skewX() and skewY()

CSS provides three functions for skew transformations.

Function Purpose Example
skew() Skews horizontally and optionally vertically. skew(15deg, 10deg)
skewX() Skews along the horizontal axis. skewX(15deg)
skewY() Skews along the vertical axis. skewY(10deg)

For a single horizontal skew, these declarations are equivalent:

transform: skew(15deg);
transform: skewX(15deg);

For a single vertical skew, these declarations are equivalent:

transform: skew(0deg, 10deg);
transform: skewY(10deg);

Important Difference When Combining Axes

A two-angle skew() transformation is not generally equivalent to applying skewX() and skewY() separately.

transform: skew(15deg, 10deg);

This produces a different transformation from:

transform: skewX(15deg) skewY(10deg);

The combined skew() function uses one transformation matrix, while the separate functions are applied as successive transformations.

The CSS Transforms specification recommends using skewX() or skewY() for new content because skew() is retained primarily for compatibility.

Combining Transform Functions

The skew() function can be combined with other transform functions in the same declaration.

For example:

.box {
  transform: translateX(30px) skew(15deg);
}

This skews the element and moves it horizontally.

It can also be combined with rotation:

.box {
  transform: rotate(10deg) skew(15deg);
}

Or scaling:

.box {
  transform: scale(1.2) skew(10deg);
}

Transform Order Matters

Transform functions are generally applied from right to left.

For example:

transform: rotate(15deg) skew(20deg);

This applies the skew before the rotation.

Reversing the order:

transform: skew(20deg) rotate(15deg);

This applies the rotation before the skew.

The resulting appearance can differ because transform operations are not generally interchangeable.

Keep all transform functions in one declaration when using the transform property. A later transform declaration replaces an earlier one rather than automatically combining with it.

CSS Custom Properties

CSS custom properties can store the angles used by skew().

For example:

.box {
  --skew-x: 15deg;
  --skew-y: 5deg;
  transform: skew(var(--skew-x), var(--skew-y));
}

Changing either custom property changes the corresponding skew angle.

Default values can also be provided:

.box {
  transform: skew(var(--skew-x, 10deg), var(--skew-y, 0deg));
}

If a custom property is not defined, the fallback angle is used.

Custom properties are useful for reusable components and interactive effects where the angle values may change.

Example

The following example compares an untransformed box with horizontal, vertical, and combined skew transformations.

HTML:

<div class="skew-demo">
  <div class="skew-item">Normal</div>
  <div class="skew-item skew-horizontal">Horizontal</div>
  <div class="skew-item skew-vertical">Vertical</div>
  <div class="skew-item skew-both">Both Axes</div>
</div>

CSS:

.skew-demo {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 30px;
  padding: 30px 20px;
}
.skew-item {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 110px;
  height: 70px;
  color: #fff;
  background-color: #3498db;
  text-align: center;
}
.skew-horizontal {
  transform: skew(20deg);
}
.skew-vertical {
  transform: skew(0deg, 15deg);
}
.skew-both {
  transform: skew(15deg, 10deg);
}
Browser Result
Normal
Horizontal
Vertical
Both Axes

The first box retains its original rectangular shape.

The second box is skewed horizontally, the third vertically, and the fourth along both axes.

The text inside each box is also skewed because the transformation applies to the element and its contents.

Slanted Button Example

The following example uses skew() to create a slanted button while keeping its text upright.

HTML:

<button class="skew-button" type="button">
  <span>Learn CSS</span>
</button>

CSS:

.skew-button {
  padding: 12px 24px;
  border: none;
  color: #fff;
  background-color: #2e86c1;
  cursor: pointer;
  transform: skew(-15deg);
}
.skew-button span {
  display: inline-block;
  transform: skew(15deg);
}
.skew-button:hover {
  background-color: #1b4f72;
}
.skew-button:focus-visible {
  outline: 3px solid #f39c12;
  outline-offset: 5px;
}
Browser Result

The button is skewed by -15deg, creating angled sides.

The inner span receives an opposite skew of 15deg, which cancels the horizontal skew for the text.

This technique is useful when a design requires angled buttons or labels without making the text difficult to read.

The button also includes a visible keyboard focus indicator.

Transition Example

The skew() function can be animated using a CSS transition.

The following example changes a box's skew when it is hovered or receives keyboard focus.

HTML:

<button class="skew-transition" type="button">
  Hover or Focus
</button>

CSS:

.skew-transition {
  padding: 15px 25px;
  border: none;
  color: #fff;
  background-color: #16a085;
  cursor: pointer;
  transform: skew(0deg);
  transition: transform 0.3s ease, background-color 0.3s ease;
}
.skew-transition:hover,
.skew-transition:focus-visible {
  background-color: #117864;
  transform: skew(15deg, 5deg);
}
.skew-transition:focus-visible {
  outline: 3px solid #f39c12;
  outline-offset: 5px;
}
@media (prefers-reduced-motion: reduce) {
  .skew-transition {
    transition: none;
  }
}
Browser Result

The button begins without a visible skew.

When hovered or focused, it transitions to a horizontal skew of 15 degrees and a vertical skew of 5 degrees.

The transition property makes the change gradual rather than immediate.

The reduced-motion media query removes the transition for users who prefer less motion.

Common Uses

The skew() function is useful for creating angled visual effects without changing an element's original layout dimensions.

  • Angled buttons: Create slanted button backgrounds while preserving readable text.
  • Decorative panels: Give rectangular elements diagonal edges.
  • Navigation effects: Create angled menu items and hover states.
  • Card designs: Apply subtle distortion to cards or promotional elements.
  • Transitions: Animate between different skew angles.
  • Combined transforms: Use skewing with rotation, scaling, or translation.
  • Custom properties: Control skew angles through reusable CSS variables.

For example, the following declaration creates a slanted panel:

.panel {
  transform: skew(-10deg);
}

The panel's vertical edges become angled while its original layout space remains unchanged.

For simpler one-axis effects, skewX() or skewY() is generally preferable.

Limitations

The skew() function has several behaviors and limitations to consider.

  • It requires one angle and accepts an optional second angle.
  • The first angle controls horizontal skewing, and the second controls vertical skewing.
  • If the second angle is omitted, it defaults to zero.
  • Nonzero angle values require a valid CSS angle unit.
  • The function must be used in a property that accepts a transform function, such as transform.
  • Skewing changes visual appearance but does not automatically change the space reserved in normal layout.
  • Child content is also transformed unless an appropriate counter-transform is applied.
  • Large skew angles can cause significant distortion or visual overflow.
  • Angles near 90 degrees can produce extreme results.
  • Using transform with a value other than none creates a stacking context.
  • Skewing does not change the element's actual DOM order or document structure.
  • Successive skewX() and skewY() functions are not generally equivalent to a two-angle skew().

Valid and Invalid Values

These declarations are valid:

transform: skew(15deg);
transform: skew(15deg, 10deg);
transform: skew(0, 20deg);
transform: skew(-0.05turn, 0.1rad);

The following declaration is invalid because the nonzero values do not include angle units:

transform: skew(15, 10);

The following is invalid because the function accepts no more than two arguments:

transform: skew(10deg, 20deg, 30deg);

Visual Overflow

A skewed element can extend beyond its original rectangular layout area.

Allow enough spacing around transformed elements to prevent unwanted overlap or clipping.

Use smaller angles when skewing elements containing important text or interactive controls.

Accessibility

Skewing text can reduce readability, especially at larger angles.

For buttons and navigation links, consider counter-transforming the text or skewing a decorative background instead of the content itself.

When animating skew transformations, respect the user's reduced-motion preference.

Browser Support

The CSS skew() function has Baseline Widely available browser support. It has been supported across major browser engines since July 2015.

Support includes Chrome, Edge, Firefox, Safari, and other modern browsers.

Because the function is well established, it can generally be used without a special fallback in modern web projects.

For current compatibility information, visit Can I Use? and search for skew().

Specifications

The skew() function is defined in the CSS Transforms Module Level 1 specification.

The specification defines its angle parameters and how the corresponding two-dimensional transformation matrix is calculated.

The skew() function is retained for compatibility. For new styles, the specification recommends using skewX() or skewY() where appropriate.

Related functions include skewX(), skewY(), rotate(), scale(), translate(), and matrix().