I just created a hover for my menu, but I have a problem with the "span".
I cant't set the width for 100%, so that I will see the all text from the button.
I know that it is possible to set the width rigidly but it should be inherit from the text width.
Can anyone help me with that?
Thanks.
jsfiddle.net/35ufuzw4/
I think you've made this a bit more complex than it needs to be. Here's an updated version of your fiddle:
DEMO
HTML:
Home
About
CSS:
* {
box-sizing: border-box;
}
.navi {
float: left;
text-decoration: none;
position: relative;
color: #000;
font-size: 14px;
padding: 0 20px;
line-height: 40px;
}
.navi:hover {
color: #582d1d;
}
.navi:before {
content: '';
position: absolute;
top: 100%;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
background-color: #000;
-webkit-transition: all 0.4s cubic-bezier(0.05, 0.06, 0.05, 0.95);
transition: all 0.4s cubic-bezier(0.05, 0.06, 0.05, 0.95);
}
.navi:hover:before {
top: 0;
}
Here's how it works:
Instead of using lots of extraneous markup, we keep things semantic using a pseudo element. The ::before pseudo element has position set to absolute, so when its top/left/right/bottom properties are all set to 0, it will be fill the space of the .navi element that has its position set to relative. Setting its top position to 100%, means that we're going to move the top all the way to the bottom. This allows you to set the top to 0 on hover and have the background-color appear to grow from the bottom up.
The .navi class itself is applied to an anchor tag, so since anchor tags are inline, we can float this element and give it some padding left and right. Using line-height, you can control how tall the element is and ensure that the text inside it is vertically aligned in the center. Add a hover pseudo class and you can change its color when the background 'grows' up behind it.
Related
I have two elements, an anchor and its pseudo-element. In the code snippet below, the pseudo-element is positioned behind its parent element. When it is hovered, the pseudo-element scales.
.btn:link,
.btn:visited {
text-transform: uppercase;
text-decoration: none;
padding: 15px 40px;
display: inline-block;
border-radius: 100px;
transition: all 0.2s;
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.4);
position: relative;
margin: 40px;
}
.btn:hover {
transform: translateY(-10px);
box-shadow: 0 20px 20px rgba(0, 0, 0, 0.2);
}
.btn-white {
background-color: #fff;
color: #777;
}
.btn::after {
content: "";
display: inline-block;
height: 100%;
width: 100%;
border-radius: 100px;
position: absolute;
top: 0;
left: 0;
z-index: -1;
transition: all 0.2s;
}
.btn-white::after {
background-color: red;
}
.btn:hover::after {
transform: scale(1.5);
}
Example
I know that when the button is not hovered, the pseudo-element is below the parent because they are in the same stacking context, and the pseudo-element has a z-index of -1. However, when the button is hovered, they are in different stacking contexts due to the parent using the transform property. Therefore, the pseudo-element covers the parent. However, the "Example" text from the parent element is still visible. Why is that?
There are three elements for the html. The <a> itself, the ::after and the text node "Example". ::after is a child to the <a>
In normal state, <a> is a positioned element but since z-index is not set, a new stacking context will not formed. ::after is also an positioned element with z-index -1, it has a stacking context and stay under <a>. In this state, both <a> and ::after under root stacking context.
When hover, transform is applied to <a>, a stacking context is formed. ::after and "Example" text node will be confined under this stacking context. Text node has auto z-index, which is greater then ::after's -1. Text node will be render above ::after.
.btn:hover::after {
transform: scale(1.5);
z-index: 1;
}
I think this overrides the stacking order of the text
see that the background is not repeated for the long text.
The red/ maroon color is an image sliced as a whole (no middle portion sliced) or in other word its a single image.
Say that I sliced the middle part so that it can repeat as the menu grows longer, how can I include it in the css?
This is how I include the single image currently.
ul a:hover{
background-image: url("<?php echo get_template_directory_uri()?>/images/slices/slanted-hover.gif");
color:#fff;
background-repeat: no-repeat;
min-width: 50px;
}
Expected result like below, where the whole word is covered by the background image:
If still not clear, please see here:
All I want to do is,
I want the black rectangle to be repeated. Ideally when I slice it's going to be there images. So how do I use it as a background for menu (putting together all there images) and repeat the middle (black rectangle) repeat?
You do not actually need to use any image for that purpose. A simply trick using just CSS 2D transform and pseudo-elements will work fine, and these two specs are widely supported across modern browsers in use.
The only modification you need for your markup is to wrap your link text in an additional <span> element, for proper z-index stacking to work.
The only caveat with this trick is that when you apply a skew, part of the skewed pseudo-element will protrude out of the bounding box of the parent element. This protrusion is dependent on the skew angle and the height of the link, but can be accounted for by setting left and right paddings on the <ul> element to ensure they don't overflow.
ul {
background-color: #eee;
list-style: none;
padding: 0 1.5rem; /* Spacing to account for skewed edges protruding out of box */
margin: 0;
overflow: hidden;
}
ul li a {
color: #000;
float: left;
padding: .75rem 1.5rem;
position: relative;
transition: all .25s ease-in-out;
}
ul li a span {
position: relative;
}
ul li a::before {
background-color: #b13131;
content: '';
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
transform: skew(-10deg);
transition: all .25s ease-in-out;
opacity: 0;
}
ul li a:hover {
color: #fff;
}
ul li a:hover::before {
opacity: 1;
}
<ul>
<li><span>Item 1</span></li>
<li><span>Item 2 that is a little bit too long</span></li>
<li><span>Item 3</span></li>
</ul>
Pure CSS solution, should work in all major browsers including IE >= 9.
ul a {
position: relative;
}
ul a:hover::after {
content: "";
z-index: -1;
position: absolute;
top: 0;
right: -.8em;
bottom: 0;
left: -.8em;
background-color: red;
transform: skewX(-15deg);
}
I have a simple css transition on the right property for a button which simply moves an arrow when you hover. The problem is that when you hover, it's not transitioning properly and if you refresh (or re-run) the JSFiddle, then you will notice that the arrow moves position after hovering.
It's like it moves back, then forwards then back again?
This appears to only happen in Firefox.
JSFiddle
Found the problem. Your span is inline, and giving it position: relative caused the issue.
Simply change to inline-block and you're good to go:
.genericBtn span {
display: inline-block;
position: relative;
}
How about using a more subtle approach by using CSS pseudo elements:
.genericBtn {
background: #ffffff;
color: #c40009;
border: 1px solid #c40009;
font-size: 20px;
margin: 10px 0 0;
padding: 20px 50px 20px 30px;
width: 300px;
position: relative;}
.genericBtn::after {
content: ">";
position: absolute;
right: 37%;
transition: all .3s ease-in;
}
.genericBtn:hover::after {
transform: translate(10px,0); }
Here is a Fiddle
Is there a way to write a CSS transition that would fade in an input text element while the user is typing?
Currently, text can fade in within a normal HTML text element because we can tell it to transition from 0 to 1 opacity; but input text doesn't exist before a user types it in.
So for example, if I type in my username, the letters that I type fade in, each one going from 0 to 1 opacity in .3 seconds.
I've tried using transition and animation, but want to keep it within CSS.
A possible way to achieve a similar effect: create a partially transparent overlay using linear-gradient and gradually reveal as you type by moving the mask position.
<div id='container'>
<input type='text'></input>
<div class='fader'></div>
</div>
$("input").on("keydown", function(e) {
var width = $("input").val().length + 1;
$(".fader").css("left", (width * 8) + 3);
});
#container {
position: relative;
height: 25px;
width: 400px;
}
input {
width: 100%;
}
input, .fader {
display: block;
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
font-family: monospace;
}
.fader {
top: 2px;
bottom: 4px;
pointer-events: none;
background: linear-gradient(90deg, transparent 0px, white, 15px, white 100%);
transition: left 1s ease;
}
Here's what it looks like as a fiddle:
http://jsfiddle.net/go7trwzx/1/
I don't believe there is any way to do this with an HTML input element, and certainly not without Javascript. Any solution would require you to create individual elements for each letter, then apply transitions to each element individually.
If you'd like a visual of what that would look like, check out the "type" example and accompanying source code here:
http://codyhouse.co/demo/animated-headlines/index.html
I'm new to HTML/CSS, and I'm learning Bootstrap.
I'm coding a Bootstrap navbar and I have a small difficulty, here's a fiddle of the work I have done.
In the HTML code there is the normal markup that goes into building a TWBS navbar, and I have added code to change the color of the active tab:
.navbar-nav a.active {
-webkit-transition: .2s;
-o-transition: .2s;
transition: .2s;
border-top: 2px solid #212121;
}
Problem: The text wrapped within the<a> tag is now slightly pushed down and I am noticing that the border-top CSS property functions more like a margin-top property.
How do I avoid this and create a border that doesn't add the margin?
You can style :before pseudo element of the active a and position it relatively to the parent element:
.navbar-nav a.active:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 2px;
}
Demo: http://jsfiddle.net/djuj5jte/5/
You could use an inset box shadow:
box-shadow: inset 0px 3px 0px 0px #212121;
This has the benefit of not changing the elements size OR requiring a pseudo element but sadly isn't supported in <=IE8 ;(
See: http://jsfiddle.net/djuj5jte/3/
You can add
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
so that the border will be part of the element width.
Useful link: https://css-tricks.com/box-sizing/