I am using a flexbox as my navigation bar at the top of my page. I have only included the code for this part because the project is an entire site. All anchor tags on my site are styled the same, with the same transform: scale(1.2) characteristic on hover. This works everywhere except in my nav. Nothing seems to scale at all inside of my nav.
Additionally on this codepen, the flexbox doesn't seem to respect the justify-content: space-around, making the anchors appear more squished together than they do on my actual site.
Codepen: https://codepen.io/colesam/pen/YxLPVW
a {
color: #646c84;
font-weight: 500;
line-height: 1.7vw;
transition: all 0.2s;
}
a:hover {
color: #ffaf54;
cursor: pointer;
transform: scale(1.2);
text-decoration: none;
}
a:focus {
color: #646c84;
text-decoration: none;
}
a:focus:hover {
color: #ffaf54;
cursor: pointer;
}
.active-indicator {
background: #ffaf54;
border-radius: 25px;
height: 2px;
margin-top: -2px;
margin-bottom: 5px;
margin-left: auto;
margin-right: auto;
opacity: 0;
transition: all 0.2s;
width: 25px;
}
.active-indicator.active {
opacity: 1;
}
#menu {
background: whitesmoke;
border: 1px solid rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: row;
justify-content: space-around;
padding: 0 25vw;
position: fixed;
left: -1;
right: -1;
top: 0;
transition: all 0.2s;
z-index: 1;
}
#menu a {
font-size: 0.9vw;
}
#menu.inactive {
opacity: 0;
}
<div id="menu">
<div id="landing-nav">
<a>Home</a>
<div class="active-indicator active"></div>
</div>
<div id="about-nav">
<a>About</a>
<div class="active-indicator"></div>
</div>
<div id="portfolio-nav">
<a>Portfolio</a>
<div class="active-indicator"></div>
</div>
<div id="resume-nav">
<a>Resume</a>
<div class="active-indicator"></div>
</div>
<div id="contact-nav">
<a>Contact</a>
<div class="active-indicator"></div>
</div>
</div>
Your nav menu has no extra width, so the flex items are packed together.
Yes, you create the illusion of width with:
#menu { padding: 0 25vw; }
But that just adds padding to the left and right of the container. The items are still packed together, and justify-content has no space to work.
revised codepen (padding removed)
Instead of padding, try using something like width: 50vw.
revised codepen (padding removed; width added)
The problem with the transform: scale() is that you have it applied to an inline-level element (a), which is not a transformable element.
Either add display: block to the anchor elements, or apply the transform to the parent div.
revised codepen (padding removed; width added; added display: block to a elements)
References:
https://drafts.csswg.org/css-transforms/#transform-property
https://drafts.csswg.org/css-transforms/#transformable-element
You have used invalid property values for your fixed nav.
Replace
left: -1;
right: -1;
with
left: 0;
right: 0;
I'm not sure why exactly transform: scale is not working, but it can be fixed by changing the display value of the div wrapping the anchor tags to flex
Codepen
Related
so I have a div which is a card and content in it. I achieved to make it moves up a bit but the transition property seems to not work.
Here is the HTML code
<div class="card">
<p> Title </p>
</div>
and here is the CSS code
.card:hover {
position: relative;
top: -10px;
transition: 1s;
}
So basically there is multiple cards and it works well every card with the .card class moves up when the mouse is over it, but it moves instantaneously, the transition does not work. Does anyone knows how to fix it? have a great day
This is because you have specified the position and transition only in the :hover block of code, meaning the transition timing is not specified until after the hover has already occurred. In other words, only the item that changes on hover (the top value) should be in the :hover.
Specify the position and transition outside the :hover block, like this for example:
.card {
position: relative;
transition: 1s
}
.card:hover {
top: -10px;
}
You can use transform: translateY
try this
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.box {
border: 1px solid black;
width: 150px;
height: 150px;
cursor: pointer;
transition: all .5s ease-in-out;
}
.box:hover {
transform: translateY(-10px);
}
<div class="box"></div>
Instead of playing with top which requires a positon attribute to move it out of flow, just add a margin to displace the element:
.card:hover {
margin-top: -20px;
margin-bottom: 20px;
transition: 1s;
}
/* for visualization purpose only */
body {
padding-top: 50px;
}
div {
border: 2px solid black;
display: flex;
justify-content: center;
align-items: center;
height: 40vh;
width: 10vw;
}
<div class="card">Card</div
I have created a horizontal menu that when you hover an item, a drop down menu appears. This is all fine. However, when you leave the menu item (to use the drop down) the drop down disappears. I understand that this is because you are no longer hovering it, but how do I solve this? Note: I don't want the drop down menu directly below it, I want a reasonable gap between the menu item and drop down (as I have it at the moment). Thanks.
HTML
<header id="header">
<div class="container">
<div id="logo"></div>
<nav class="header-menu">
ABOUT
<div class="about-dropdown">
CORE SERVICES
AT&L
HSEQ
CLIENTS
CONTACT
</div>
SERVICES
FACILITIES
CONTACT
</nav>
<div id="hamburger"></div>
<!--<div id="box-shadow-menu"></div>-->
</div>
</header>
CSS
#header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100px;
user-select: none;
display: block;
transition: all 0.8s;
line-height: 100px;
z-index: 1000;
transform: translateX(0);
backface-visibility: hidden;
margin: 0;
}
header .container {
width: 1440px;
height: 100px;
border-bottom: 0.75px solid rgba(255,255,255,0.1);
}
#logo {
width: 55px;
height: 55px;
float: left;
margin-top: 27px;
background-image: url(../images/logo_white.png);
background-size: cover;
}
nav.header-menu {
float: right;
height: 96px;
vertical-align: middle;
padding-top: 1px;
}
.header-menu-item {
font-family: 'Montserrat', sans-serif;
font-size: 11px;
font-weight: 800;
margin-left: 20px;
text-decoration: none;
color: #ffffff;
line-height: 96px;
letter-spacing: 0.5px;
transition: 0.55s;
}
.toggle {
opacity: 0.3;
}
.current {
border-bottom: 2px solid #fff;
padding-bottom: 40px;
}
.about-dropdown {
position: absolute;
background-color: #fff;
min-width: 160px;
box-shadow: 0 0 4px 3px rgba(0,0,0,0.1);
z-index: 3000;
margin-top: 35px;
margin-left: -35px;
border-radius: 3px;
display: none;
transition: 0.8s;
}
.about-dropdown a {
display: block;
text-decoration: none;
padding: 0px 28px;
font-family: 'Montserrat', sans-serif;
font-size: 11px;
font-weight: 800;
margin: 0;
line-height: 50px;
border-bottom: 1px solid rgba(0,0,0,0.1);
}
.header-menu-item:hover + .about-dropdown {
display: block;
}
On the 'a' tag, add a height or padding-bottom to it on hover. Your 'a' tag might need to be positioned absolute so that its height won't affect the height of your header.
Something like the below
.about-dropdown a:hover {
padding-bottom: 30px; /*height dependent on the gap you want to fill*/
position: absolute;
}
Unfortunately, I could not get your example to work. I did create a little demo of a CSS only solution to your problem.
It allows users to trigger the submenu by hovering the menu item. They can then keep the submenu visible by hovering it. When their cursor leaves the submenu, the submenu will be hidden after some specified delay, I chose 1 second in my demo. If users hover the submenu again within this delay, the submenu is not hidden. This allows users not only to move their cursor from the menu item to the submenu, but also makes it so that the submenu is not hidden immediately when users accidentally move their cursor to the left or right of the submenu.
.trigger {
box-sizing: border-box;
position: relative;
width: 120px;
margin: 0 0 50px;
padding: 10px;
background: #bada55;
text-align: center;
}
.sub {
box-sizing: border-box;
position: absolute;
top: 100px;
left: 0;
width: 120px;
background: #4863a0;
color: #fff;
text-align: left;
/* hide element for now */
max-height: 0; overflow: hidden;
opacity: 0;
/* make submenu not hoverable when opacity transition finished,
* do this instantaneously */
transition: max-height 0s 1.5s,
/* hide the submenu after 1 second, in 400ms */
opacity .4s 1s;
/* prevent users from showing submenu when hovering hidden element */
pointer-events: none;
}
/* sub elements can be hovered */
.sub > * {
pointer-events: auto;
}
/* show submenu when trigger or menu itself is hovered */
.sub:hover,
.trigger:hover .sub {
max-height: 500px;
opacity: 1;
transition-delay: 0s;
}
/* give items some spacing */
.item:not(:last-child) {
padding: 10px 10px 5px;
}
.item:last-child {
padding: 10px;
}
<div class="trigger">HOVER ME
<div class="sub">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
</div>
</div>
The idea is to (ab)use CSS transitions. We hide the submenu completely and set a transition that is delayed. Then, when hovered, we set the delay to zero. What this will do is show the submenu immediately, but hide it only after some delay. This sort of works, but now the submenu can be shown when users hover the hidden element. To prevent this, we make the submenu have no height (max-height: 0) and hide its sub elements (overflow: hidden). Browsers may now still decide to trigger the hover element, so we make sure they do not by also setting pointer-events: none. All of this should also be delayed, hence the transition on max-height. Finally, we make it so that the submenu can actually be hovered when it is shown by setting pointer-events: auto for the elements in it. Unfortunately, it is not possible to transition to max-height: none, so we specify some very large value, I used 500px in the demo.
I have a list of div elements with a big letter (A, B, C or D) and span (description) inside. I would like to center these span elements horizontally respect to each parent div, but keeping a fixed distance among all big letters. I'm looking for something like this:
The centering part is done with:
span{
position: absolute;
left: 50%;
transform: translateX(-50%);
}
But when I apply a simple transition (opacity for example) to div elements, the first letter in span elements is moved from it's place. If I remove the transition or transform property the issue goes away, but I need both (transform for centering).
Question: How to fix the issue with transition and transform, or how to center span elements without transform, but keeping the fixed distance among big letters?
Here is the code, and a DEMO:
HTML:
<div class="elements">
<div>A<span>Description</span></div>
<div>B<span>Really Long Description</span></div>
<div>C<span>Description</span></div>
<div>D<span>Description</span></div>
</div>
SCSS:
.elements{
margin-left: 50px;
div{
position: relative;
display: inline-block;
font-size: 40px;
margin: 0 10px;
opacity: 0.7;
transition: 0.3s;
&:hover{
opacity: 1;
span{
opacity: 1;
}
}
span{
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
transition: 0.3s;
font-size: 15px;
white-space: nowrap;
pointer-events: none;
opacity: 0;
}
}
}
Depending on compatibility requirements, you could always use the flex box model, and it's handy justify-content property, like so:
.elements {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex; /*Only one out of the above that's really needed...*/
justify-content: space-around;/*Only one out of the below that's really needed...*/
-ms-flex-pack: distribute;
justify-content: space-around;
}
.elements >div {
position: relative;
display: inline-block;
opacity: 0.7;
font-size: 30pt;
text-align: center;
transition: 0.3s opacity;
}
.elements >div:hover {
opacity: 1;
}
.elements >div >div {
font-size: 12pt;
white-space: nowrap;
}
<div class="elements">
<div>A
<div>Description</div>
</div>
<div>B
<div>Long Description</div>
</div>
<div>C
<div>Description</div>
</div>
</div>
Your question has a very nice solution, tables! While they should only be used for tabular data semantically, they do have some nice display properties, and they'be been used since forever so compatibility is not an issue.
body{
display:table;
table-layout:fixed;
}
.elements{display:table-row;}
.elements >div {
width:20%; /*100% / Number of cells*/
display:table-cell;
padding:0 10px; /*There needs to be a little spacing otherwise it looks bad :) */
opacity: 0.7;
font-size: 30pt;
text-align: center;
transition: 0.3s opacity;
}
.elements >div:hover {
opacity: 1;
}
.elements >div >div {
font-size: 12pt;
white-space: nowrap;
}
<div class="elements">
<div>A
<div>Description</div>
</div>
<div>B
<div>Long Description</div>
</div>
<div>C
<div>Description</div>
</div>
<div>D<div>Description</div></div>
</div>
I have not found a way to make work properly transition and transform properties (Firefox at least). But I found a way to center each span elements inside it parent div, keeping distance among big letters (A, B, C & D).
See the SOLUTION DEMO, and the code added (SCSS):
$div-width: 40px;
$span-width: 200px;
.elements{
div{
width: $div-width; // fixed width
text-align: center; // center text
span{
width: $span-width; // big fixed width
left: -($span-width/2 - $div-width/2); // -(200px / 2 - 40px / 2)
}
}
}
I know that there are four different position values:
static
relative
fixed
absolute
What's really bothering me is the position of an element when i increase the marigin of it. Something like below.
HTML
<header>
<h1>Welcome to Online Shopping System <button type="submit" onclick = "location.href = 'adminlogin.php';" id = "button" >Admin</button></h1>
</header>
<nav id = "navigation">
<ul>
<li>Home</li>
<li>View</li>
<li>Login</li>
<li>Signup</li>
</ul>
</nav>
Notice the grey background color effect that I have applied in the hover.
It clearly shows I'm messing up somewhere with the positioning, and it would be a plus if you could enlighten on overflow property too.
CSS
header > h1
{
width: 100%;
background-color: brown;
height: 45px;
color: white;
text-indent: 65px;
font-family: "Lucida Sans Unicode","Lucida Grande",Garuda,sans-serif;
padding: 0;
margin: 0;
}
nav ul li
{
float:left;
list-style-type: none;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
nav > ul > li > a
{
position: relative;
overflow: hidden;
color: white;
background-color: none;
display: block;
line-height: .1em;
padding: 0.5em 0.5em;
text-decoration: none;
margin-left: 80%;
}
nav li > ul li a
{
color: #111;
display: block;
line-height: 2em;
padding: 0.5em 2em;
text-decoration: none;
}
#navigation
{
background-color: brown;
margin: 0;
overflow: hidden;
height: 45px;
}
nav li:hover
{
background-color: #666;
}
this is how i got it, I Think, how You wanted?
Remove margin-left: 80%,
Add these into your CSS
nav ul {
display: flex;
justify-content: center;
width: 100%;
padding: 0px;
}
nav ul li {
width: 25%;
padding: 5px;
}
Does this helped?
this might help u a bit, sorry about my english.
Overflow:
hidden: hides everything what is not inside the area, no scrollbars.
overlay: shows scrollbars if needed and overlays scrollbars top of contents
scroll: show scrollbars normally
visible: shows all the child elements of current content, no area limitations.
Also you can set just overflow-x: hidden to prevent horizontal scrollbar for example and overflow-y: overlay to put scrollbar top of content.
Position:
fixed: dependable window area, stays exactly where u point it
relative: all child elements dependable to relative area
absolute: dependable to a first upper relative area, scrolls with contents
static: normal state
Examples:
<div style='position: relative; width: 100px; height: 20px;'>
<!-- THIS GOES TO TOP OF WINDOW LEFT CORNER AND STAYS THERE -->
<div style='position: fixed; top: 0px; left: 0px;'></div>
<!-- THIS GOES TOP OF UPPER RELATIVE CONTENT RIGHT TOP CORNER -->
<div style='position: absolute; top: 0px; right: 0px;'></div>
</div>
<div style='position: relative; overflow: hidden'>
<!-- THIS DIV YOU JUST NOT BASICALLY SEE, BECOUSE OF OVERFLOW HIDDEN -->
<div style='position: fixed; right: 0px; bottom: 0px;'></div>
</div>
I hope this helps You to understand it little better :)
#border {
position: static;
z-index: 1;
width: 120px;
height: 120px;
margin-left: 92% ;
padding: 15px;
border-radius: 11px;
background: white;
opacity: 0.2;
}
#text {
margin-left: 93%;
z-index: 2;
color: white;
font-weight: bold;
}
<div id="border"></div>
<div id="text">Users online</div>
I can't post the image here, cuz I have less than 10 reputation, so try to imagine it please. I want to place it's "Users online" inside the border, how should I do this? Thanks.
I'm assuming you are trying to have an element with a semitransparent background.
Since you are using the opacity property on the element with an id of border.
The problem here is that z-index will not have any effect, if the position is set to static, which is the default value for div elements.
The other thing is, that you should be using a relative positioned parent to make your life easier and have more control over the elements since positioned elements will leave the normal document flow and result in new stacking order.
Here you can find good information on the the z-index property, stacking and the document flow.
This is one solution to your problem.
body {
background:black;
}
.holder {
position:relative;
}
#border {
position: absolute;
z-index:1;
right:0;
width: 120px;
height: 120px;
padding: 15px;
border-radius: 11px;
background: white;
opacity: 0.2;
}
#text {
position: absolute;
z-index:2;
right:0;
width: 120px;
height: 120px;
padding: 15px;
text-align: center;
color: white;
font-weight: bold;
}
<div class="holder">
<div id="border"></div>
<div id="text">Users online</div>
</div>
But i would actually try to solve this with a different approach, because i find the above solution a bit to complex and it involves to much positioning, so if all you need is a semitransparent background just make use of the background property with an rgba value. Here is an example.
.user-panel {
float:right;
height: 120px;
width: 120px;
padding: 15px;
border-radius: 11px;
/* fallback for browser that do not support rgba */
background: #ccc;
/* semitransparent background */
background: rgba(0, 0, 0, .2);
text-align: center;
color: white;
}
/* clear the float using the pseudo after element */
user-panel:after {
clear: both;
display: block;
visibility: hidden;
height: 0px;
}
<header>
<div class="user-panel">Users online</div>
</header>
Hope that helps.
Change
position: static;
to
position: absolute;
for #border. That way, border will be "removed from the flow" (i.e. other elements will ignore it). You may need to adjust the margin-left property for #text so it properly aligns.
Fiddle: https://jsfiddle.net/xzdmLt33/1/