I have this project, with this navbar
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:
- 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):
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
- is not in its place, like I want (seems to be centered, but I want that it will be on the left side)
- 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:
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
transform: translate(45vw, 45vw);
that seems to solve something, but only on 900px exactly width of the viewport
so I need to use a lot @media
to make it work :(
here an example:
300px
the black line of the border disappears completely, the text hasn't any gap between
1500px
the gaps are much bigger, the black line is moving to the right, most of the text isn't visible
now another bug that I solved is using -90deg
intead of 90deg
to make the border to the right.
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
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>
CodePudding user response:
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>