6

I'm using transforms to make my <li>s as below enter image description here

here is my codes

.tab-nav {
    width: 100%;
    height: 40px;
    margin-top: 100px;
}

.tab-nav-li {
    display: inline-block;
    border: solid 1px gray;
    margin: 0 5px;
    min-width: 170px;
    min-height: 40px;
    line-height: 40px;
    text-align: center;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    transform: perspective(38px) rotateX(2deg);
    transform-origin: bottom;
}
<div class="tab-nav">
    <ul>
        <li class="tab-nav-li">
            <span>The first tab</span>
        </li>
        <li class="tab-nav-li">
            <span>The second tab</span>
        </li>
        <li class="tab-nav-li">
            <span>The third tab</span>
        </li>
    </ul>
</div>

li tags is transformed as my expecting, but its content was also transformed as well and this make a blurry text (as you can see it's not clear). Is there any way to avoid this?

One more question, viewing this on FF browser, the left side border looks not smooth. Do you know why and how to solve this issue? enter image description here

Regards, Ken


Updated on May 9, 2017 - 5:19PM

I want to add a class call "highlighted" to fill background color for li tag.

.tab-nav {
  width: 100%;
  height: 40px;
  margin-top: 100px;
}

.tab-nav-li {
  display: inline-block;
  margin: 0 5px;
  min-width: 170px;
  min-height: 40px;
  line-height: 40px;
  perspective: 38px; /*Declaring here*/
  position: relative;
}

.tab-nav-li:before {
  content: "";
  width: 100%;
  height: 40px;
  position: absolute;
  border: solid 1px gray;
  border-top-left-radius: 5px;
  border-top-right-radius: 5px;
  transform: rotateX(2deg);/*Then rotate*/
  transform-origin: bottom;
}

span {
  display: block;
  text-align: center;
}

.highlighted {
  background-color: darkgray;
}
<div class="tab-nav">
    <ul>
        <li class="tab-nav-li highlighted">
            <span>The first tab</span>
        </li>
        <li class="tab-nav-li">
            <span>The second tab</span>
        </li>
        <li class="tab-nav-li">
            <span>The third tab</span>
        </li>
    </ul>
</div>
 

As you can see the above result, the color was filled but not fit in borders.

.tab-nav {
  width: 100%;
  height: 40px;
  margin-top: 100px;
}

.tab-nav-li {
  display: inline-block;
  margin: 0 5px;
  min-width: 170px;
  min-height: 40px;
  line-height: 40px;
  perspective: 38px; /*Declaring here*/
  position: relative;
}

.tab-nav-li:before {
  content: "";
  width: 100%;
  height: 40px;
  position: absolute;
  border: solid 1px gray;
  border-top-left-radius: 5px;
  border-top-right-radius: 5px;
  transform: rotateX(2deg);/*Then rotate*/
  transform-origin: bottom;
}

span {
  display: block;
  text-align: center;
}

.highlighted:before {
  background-color: darkgray;
}
<div class="tab-nav">
    <ul>
        <li class="tab-nav-li highlighted">
            <span>The first tab</span>
        </li>
        <li class="tab-nav-li">
            <span>The second tab</span>
        </li>
        <li class="tab-nav-li">
            <span>The third tab</span>
        </li>
    </ul>
</div>

And above way. color was filled and fitted in borders but it overlay the text.

Please help me solve this issue.

Thanks, ken

2 Answers 2

2

First declare a perspective on parent element to create 3d transform on multiple elements, what we did here is used li as perspective and even rotated that, so it created blur on span tag text. Instead use pseudo selector to rotate at X-axis and declare perspective on li element, as below,

The perspective CSS property determines the distance between the z=0 plane and the user in order to give to the 3D-positioned element some perspective.

.tab-nav {
  width: 100%;
  height: 40px;
  margin-top: 100px;
}

.tab-nav-li {
  display: inline-block;
  margin: 0 5px;
  min-width: 170px;
  min-height: 40px;
  line-height: 40px;
  perspective: 38px; /*Declaring here*/
  position: relative;
}

.tab-nav-li:before {
  content: "";
  width: 100%;
  height: 40px;
  position: absolute;
  border: solid 1px gray;
  border-top-left-radius: 5px;
  border-top-right-radius: 5px;
  transform: rotateX(2deg);/*Then rotate*/
  transform-origin: bottom;
}

span {
  display: block;
  text-align: center;
}
<div class="tab-nav">
    <ul>
        <li class="tab-nav-li">
            <span>The first tab</span>
        </li>
        <li class="tab-nav-li">
            <span>The second tab</span>
        </li>
        <li class="tab-nav-li">
            <span>The third tab</span>
        </li>
    </ul>
</div>

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you so much, @frnt I want to add a class called "highlighted" to fill background-color for the first tab. If I declare css as .highlighted { background-color: darkgray; } so the color was filled but not fit in the border. If i declare .highlighted:before { background-color: darkgray; } so the color was filled and fitted in the border but it overlay the text in span tag. Please see updated question. Could you help me this issue. Thank,
@Ken if you need background-color with same effect as rotated at x-axis then you need to add background to pseudo selector and as both border, background are same so it's border is hidden. Check this jsfiddle.net/4gw31grx
I just wanna add background-color for the li with "highlighted" class, and others should be white (none color). I updated the question, please take a look. Thank you.
@Ken as I have used pseudo selector, so you need to use nth-child and then target that instead of adding a new class to li tag jsfiddle.net/4gw31grx/1
Is there anyway to use highlighted class? Actually, they are tabs of a menu, and "highlighted' class was added by using ng-class (angularjs). So I'm not sure which tab, first/second or third tab will be filled color. It just an example case. That why I must use that class to fill background-color, @frtn
|
1

If you set those spans to display:inline-block, you can "reset" the transform on them by essentially applying the opposite effect. That will clear up the skewing of the content:

.tab-nav {
    width: 100%;
    height: 40px;
    margin-top: 100px;
}

.tab-nav-li {
    display: inline-block;
    border: solid 1px gray;
    margin: 0 5px;
    min-width: 170px;
    min-height: 40px;
    line-height: 40px;
    text-align: center;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    transform: perspective(38px) rotateX(5deg);
    transform-origin: 50%;
}

.tab-nav-li span {
    display: inline-block;
    transform: perspective(38px) rotateX(-5deg);
}
<div class="tab-nav">
    <ul>
        <li class="tab-nav-li">
            <span>The first tab</span>
        </li>
        <li class="tab-nav-li">
            <span>The second tab</span>
        </li>
        <li class="tab-nav-li">
            <span>The third tab</span>
        </li>
    </ul>
</div>

As for the jagged border rendering in FF, it actually looks fine on my MacBook in FF. The simplest solution may be to just go with an image for a background rather than using transforms for your tab outlines.

Hope it helps!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.