Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS transformation without transforming its content

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

like image 382
Ken Avatar asked May 09 '17 04:05

Ken


2 Answers

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>
like image 144
frnt Avatar answered Oct 20 '22 05:10

frnt


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!

like image 1
Rich Avatar answered Oct 20 '22 06:10

Rich