How to skew element but keep text normal (unskewed)
Asked Answered
K

7

83

Is it possible to reproduce this image using only CSS?

enter image description here

I want to apply this to my menu, so the brown background appears on hover instance

I don't know how to do this, I only have;

.menu li a:hover{
     display:block;
     background:#1a0000;
     padding:6px 4px;
}
Kroon answered 30/7, 2013 at 12:51 Comment(0)
S
158

skew a parent element (li in this example) and inverse skew its child elements:

CSS Menu skewed buttons diagonal borders

nav ul {
  padding: 0;
  display: flex;
  list-style: none;
}
nav li {
  transition: background 0.3s, color 0.3s;
  transform: skew(20deg); /* SKEW */
}

nav li a {
  display: block; /* block or inline-block is needed */
  text-decoration: none;
  padding: 5px 10px;
  font: 30px/1 sans-serif;
  transform: skew(-20deg); /* UNSKEW */
  color: inherit;
}

nav li.active,
nav li:hover {
  background: #000;
  color: #fff;
}
<nav>
  <ul>
    <li><a href="#">Home</a></li>
    <li class="active"><a href="#">Products</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>
Sulph answered 30/7, 2013 at 13:12 Comment(7)
yeah... and thanks too to Reformulate my question.. i don't remember that skew name.. :)Kroon
this: display:inline-block; don't work IE8 or less... so i put some *float:left; hack to make this "inline" on IE. But when i mouse over the menu, (on IE8) i can't setup some normal background (without the skew). Any tips?Kroon
@Kroon sure, use images and help us kill IE8Sulph
That only works if you have an element nested inside, I'd like to just effect the text.Mussel
@Mussel you cannot; so wrap your text into a <span> and do the same.Sulph
@RokoC.Buljan <--- what he said. Please.... nobody ever do this in practice... just wrap it in a span and give it those same skew properties and maybe a display: inline-block or something.Faxan
I could not revert the skew of a span child. Had to use a div instead. Possibly something to do with the display property though, not sure.Amie
H
10

Here is a fiddle for use across different browsers - I created in a couple of minutes.

Try playing with the arguments, I used :before and :after to do this.

https://jsfiddle.net/DTBAE/

Halley answered 30/7, 2013 at 13:8 Comment(4)
Any chance you could explain this? I'm kinda at a loss for what it's doing and would like to learn a bit about :before and :afterAccounting
I would have gone for the transform method as well, but this has better browser support!Glauce
While this is almost Xbrowser (:after, :before) you can only get an angle of 45°Sulph
You can adjust the border-widths to change the slope. jsfiddle.net/DTBAE/1Glauce
A
6

You can use the transform: skew(X, Y) property to achieve this. Creating a skewed outer container, then skew the opposite amount on an inner container to skew the text back to being straight. See this fiddle for example;

http://jsfiddle.net/UZ6HL/4/

From what you have said, I believe this is what you want, if not please clarify when the item should display the background.

Accounting answered 30/7, 2013 at 13:3 Comment(0)
S
5

.skew {
  background: green;
  color: #fff;
  padding: 50px;
  transform: skewX(-7deg);
  font-size: 20px;
  font-weight: 700;
}

.skew p {
  transform: skewX(7deg);
}
<div class="skew">
  <p>This is caption</p>
</div>

Here's an example

Sparklesparkler answered 23/6, 2017 at 8:27 Comment(0)
B
2

To have IE support just add -ms-transform: skew(20deg, 0deg); beside all the other transform: skew(20deg, 0deg);s.

Bordello answered 23/3, 2015 at 8:19 Comment(0)
C
1

You can use clip-path to make results like these. For example:

* {
  box-sizing: border-box;
}

body {
  padding: 0;
  margin: 0;
}

ul {
  display: flex;
  width: 100%;
  flex-direction: row;
  gap: 20px;
  background: #000;
  padding: 0 10px;
  justify-content: flex-end;
}

li {
  list-style-type: none;
  clip-path: polygon(20% 0%, 100% 0, 80% 100%, 0% 100%);
  background: blue;
  padding: 10px 50px;
}

a {
  color: #fff;
}
<ul>
  <li><a href="">Home</a></li>
  <li><a href="">About</a></li>
</ul>

You can generate your clip from here and use it in your code.

Here is a working Fiddle for reference

Chenault answered 22/1, 2022 at 13:10 Comment(0)
D
0

NOTE: SPAN is NOT affected by transform CSS functionality, so you will need a DIV or change span to display: block; otherwise they will NOT be affected.

So just put the TEXT inside a separate div and unskew it.

example wrapper div is:

 transform: skewx(35deg)

but text div is:

transform: skewx(-35deg); 

here is codepen: https://codepen.io/dmitrisan/pen/NWaYEzV

Demodena answered 2/1, 2022 at 15:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.