Reputation:
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:
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
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?
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>
Upvotes: 1
Views: 197
Reputation: 274307
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>
Upvotes: 1