Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

positioning a rotated 90deg element isn't responsive

I have this project, with this navbar
enter image description here

like you see I am using flexbox, and it is correctly viewed.

but they tell me that I need that the navbar is rotated, and the text be viewed like so:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  • rotated 90deg.
  • hover working fine with the same rotation.
  • the black line at the bottom should be on the right side.

something like this (this is only photoshopped image for you, so you can understand):

enter image description here

and for you can seem easy but I know some CSS, and I know how to rotate it

by using:

   transform: rotate(90deg);

but here is the problem, isn’t positioned correctly.

so before I will tell you the problems, I will put you my first code without rotating (so it will be easier to you to debug with the next following code)

:root {
  --height: 3rem;
  --triangle-width: 1rem;
  --bg: #ccc;
  --angle: 20deg;
  --text-color: black;
}

* {
  box-sizing: border-box;
}

nav {
  display: flex;
  gap: var(--triangle-width);
  color: var(--text-color);
  position: relative;
  margin: 0 var(--triangle-width);
}

nav::before {
  content: "";
  position: absolute;
  bottom: 0;
  background: var(--text-color);
  height: 0.2rem;
  width: 100%;
}

nav div {
  display: grid;
  place-items: center;
  height: var(--height);
  width: calc(100% - (var(--triangle-width) * 2));
  position: relative;
  text-transform: uppercase;
}

nav div:hover {
  background-color: var(--bg);
}

nav div:hover::before {
  content: "";
  position: absolute;
  top: 0;
  left: calc(-1 * (var(--triangle-width) / 2));
  height: var(--height);
  width: var(--triangle-width);
  background-color: var(--bg);
  transform: skewX(calc(-1 * var(--angle)));
}

nav div:hover::after {
  content: "";
  position: absolute;
  top: 0;
  right: calc(-1 * (var(--triangle-width) / 2));
  height: var(--height);
  width: var(--triangle-width);
  background-color: var(--bg);
  transform: skewX(var(--angle));
}

nav div::before,
nav div::after {
  z-index: -1;
}

nav::before {
  z-index: 1;
}
<nav>
  <div>instagram</div>
  <div>microsoft</div>
  <div>facebook</div>
  <div>linkedin</div>
  <div>youtube</div>
</nav>

the snippet you see up here is the normal flex navbar without rotating

list of problems

  • the half element is invisible, and seems to overflow

enter image description here

  • is not in its place, like I want (seems to be centered, but I want that it will be on the left side)

enter image description here

  • if I expand the height is not changing, but if I change the width is changing.

I want that if is rotated, the width of the nav is the height of the device.
so if the device is smaller remains the same as the viewport width is higher… but the difference happens only if the height changes.

here are some examples:

small width
enter image description here

bigger width
enter image description here

as you see there is some gaps that change a lot, I just want it will be responsive like the code without transform: rotate(90deg)



now that you know the problem, I will tell how I tried to solve it

I used this code:
enter image description here

transform: translate(45vw, 45vw);

that seems to solve something, but only on 900px exactly width of the viewport

enter image description here

so I need to use a lot @media to make it work 🙁

here an example:

500px
the text is smaller, no gaps
enter image description here

300px
the black line of the border disappears completely, the text hasn’t any gap between
enter image description here

1500px
the gaps are much bigger, the black line is moving to the right, most of the text isn’t visible
enter image description here


now another bug that I solved is using -90deg intead of 90deg to make the border to the right.
enter image description here

so what I want?

  • a simple css solution,
  • that makes the nav responsive to the height of the device
  • with the same behavior of grid 1fr (but in my case I am using flex then rotate it)
  • the text need to be always visible inside the height of the device
  • don’t change with the width, change only with the height
  • gaps don’t get bigger a lot
  • border line need to be on the right

enter image description here

ok. now here my code:

:root {
  --height: 3rem;
  --triangle-width: 1rem;
  --bg: #ccc;
  --angle: 20deg;
  --text-color: black;
}

* {
  box-sizing: border-box;
}

nav {
  display: flex;
  gap: var(--triangle-width);
  color: var(--text-color);
  position: relative;
  margin: 0 var(--triangle-width);
  transform: rotate(-90deg) translate(-45vw, -45vw);
}

nav::before {
  content: "";
  position: absolute;
  bottom: 0;
  background: var(--text-color);
  height: 0.2rem;
  width: 100%;
}

nav div {
  display: grid;
  place-items: center;
  height: var(--height);
  width: calc(100% - (var(--triangle-width) * 2));
  position: relative;
  text-transform: uppercase;
}

nav div:hover {
  background-color: var(--bg);
}

nav div:hover::before {
  content: "";
  position: absolute;
  top: 0;
  left: calc(-1 * (var(--triangle-width) / 2));
  height: var(--height);
  width: var(--triangle-width);
  background-color: var(--bg);
  transform: skewX(calc(-1 * var(--angle)));
}

nav div:hover::after {
  content: "";
  position: absolute;
  top: 0;
  right: calc(-1 * (var(--triangle-width) / 2));
  height: var(--height);
  width: var(--triangle-width);
  background-color: var(--bg);
  transform: skewX(var(--angle));
}

nav div::before,
nav div::after {
  z-index: -1;
}

nav::before {
  z-index: 1;
}
<nav>
  <div>instagram</div>
  <div>microsoft</div>
  <div>facebook</div>
  <div>linkedin</div>
  <div>youtube</div>
</nav>

>Solution :

I would simplify your code and only consider 4 properties to rotate and correctly set the height of your element. I also updated your HTML code for a better semantic markup

:root {
  --height: 3rem;
  --triangle-width: 1rem;
  --bg: #ccc;
  --text-color: black;
}
nav {
  display: flex;
  color: var(--text-color);
  border-bottom: 0.2rem solid var(--text-color); 
  position: absolute;
  min-width: fit-content;  /* in case we have small height */
  /* you need the below */
  inset: 0 auto auto var(--triangle-width);
  width: calc(100vh - 2*var(--triangle-width));
  transform-origin: 0 0;
  transform: rotate(-90deg) translate(calc(-100% - var(--triangle-width)));
  /**/
}
nav ul {
  display: flex;
  width: 100%;
  justify-content: space-around;
  gap: var(--triangle-width);
  margin: 0;
  padding: 0;
  list-style: none;
}
nav ul li {
  display: grid;
  place-items: center;
  min-height: var(--height);
  position: relative;
  z-index: 0;
  text-transform: uppercase;
  cursor: pointer;
}

nav ul li:before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0 calc(-1*var(--triangle-width));
  clip-path: polygon(var(--triangle-width) 0, calc(100% - var(--triangle-width)) 0, 100% 100%, 0 100%);
}

nav ul li:hover:before {
  background: var(--bg);
}
<nav>
  <ul>
    <li>instagram</li>
    <li>microsoft</li>
    <li>facebook</li>
    <li>linkedin</li>
    <li>youtube</li>
  </ul>
</nav>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading