Here is a code from W3Schools on how to create a ripple effect button.
.button {
position: relative;
background-color: #4CAF50;
border: none;
font-size: 28px;
color: #FFFFFF;
padding: 20px;
width: 200px;
text-align: center;
-webkit-transition-duration: 0.4s; /* Safari */
transition-duration: 0.4s;
text-decoration: none;
overflow: hidden;
cursor: pointer;
}
.button:after {
content: "";
background: #f1f1f1;
display: block;
position: absolute;
padding-top: 300%;
padding-left: 50%;
margin-left: -20px !important;
margin-top: -120%;
opacity: 0;
transition: all 15s;
}
.button:active:after {
padding: 0;
margin: 0;
opacity: 1;
transition: 0s;
}
Can someone help me understand the code bit by bit, especially why the padding and margin in the button:after are so highly set and how the zero values in the button:active:after affect the animation?
Any help will be highly appreciated. (I know the basic of padding and margin, but I think that I am not getting the 'after' class and the technique used).
:after is not a class is a pseudo-element that it's used to add content to the content of an element .see here ::after
so it uses that pseudo-element to create a new space with CSS that it's not defined in your initial HTML . it's like making another element inside the button
for eg if you had a structure like this :
.no_pseudo, .with_pseudo {
width:100px;
height:100px;
background:red;
margin:40px 0
}
.likeAfter {
background:blue;
width:50%;
margin:0 auto;
height:100%;}
.with_pseudo {
position:relative;
}
.with_pseudo:after {
content:"";
position:absolute;
background:blue;
width:50%;
margin:0 auto;
height:100%;
lefT:0;
right:0;}
<div class="no_pseudo">
<div class="likeAfter">
</div>
</div>
<div class="with_pseudo">
</div>
as you can see, the :after element can be used just like a child element inside a div. but you can achieve that just by using CSS .you don't have to change the HTML structure.
so this trick is using :after , which has a background: #f1f1f1; and it's positioned under the button ( margin-top:-120% ) . and then, when you click on the button , it has (margin:0 ) that's how this effect is done
also with paddings and opacity.
i would've done it differently :
.button {
position: relative;
background-color: #4CAF50;
border: none;
font-size: 28px;
color: #FFFFFF;
padding: 20px;
width: 200px;
text-align: center;
-webkit-transition-duration: 0.4s; /* Safari */
transition-duration: 0.4s;
text-decoration: none;
overflow: hidden;
cursor: pointer;
z-index:2;
}
.button:after {
content: "pseudo element >!<";
color:green;
background: #f1f1f1;
display: block;
position: absolute;
bottom:0;
left:0;
height:0%;
width:0%;
opacity: 0;
transition: all 3s;
}
.button:focus:after {
width:50%;
height:100%;
opacity: 1;
}
<button class="button">
I AM A BUTTON
</button>
i positioned the :after at the bottom-left of the button , with width:0%;height:0%;opacity:0 ;
then, when i click on the button, i added width:50%;height:100%;opacity:1 on the :after and that's how you get that effect . maybe is not exactly the same as in your example but it works.
also added some content:"" to the :after element. you can add text,images etc. almost anything. but if you don't want to add anything, you must use content:"" and leave it empty, otherwise the :after is not created.
:before is the same as after > see here more about pseudo elements
css_pseudo_elements or here Pseudo-elements
there is much to talk about this things, but i hope you kind of understood what's going on with the pseudo-elements and with this effect. let me know. cheers !
EDIT AFTER COMMENT :
1. ' transition backwards ' is because of the :active state ( :active ) . the button has the :active state only when you click on it . after that it's not active anymore and :after goes back to it's original style
and because it has transition:15s it takes 15 sec to get back to it's original position and color.
the same with the ripple effect. you click on the button, the effects starts , :after gets from one style to another , for example from opacity:0 to opacity:1 then because the button doesn't have :active state anymore, :after returns to it's original style of opacity:0 , all this happens in 15 seconds ( because of the transition:15s )
2
content:"" inserts the space for the :after or :before into the HTML structure
you need content:"" on :after because , as i said in the beginning ,
::after is a pseudo element which allows you to insert content onto a page from CSS (without it needing to be in the HTML). While the end result is not actually in the DOM, it appears on the page as if it is
key word content . so even if you don't insert text or images but you just want to insert an empty space , you need to set up a content:"" which means empty but still there .
elem:after{content:""} generates a space with width:0;height:0 after the element.
i will make two short examples , one with something inside content:"" one with nothing inside it
h1:before {
content:"i am before < < < ";
font-size:14px;
color:red;
}
h1:after {
content:" > > > i am after";
font-size:14px;
color:blue;
}
h2:before {
content:"";
background:red;
width:20px;
height:20px;
position:absolute;
}
h2:after {
content:"";
background:blue;
width:20px;
height:20px;
position:absolute;
}
<h1>Text Before me </h1>
<h2>Just empty content </h2>
Related
I'm trying to increase the duration of CSS :active and found this thread How to increase the duration of :active in css? I tried this but it didn't work on my code.
here my code:
li {
transition:0s 1s;
}
li:active:before {
content:"hello !";
z-index:99999999;
position:fixed;
bottom:0px;
width:100%;
background:black;
text-align:center;
color:white;
padding:10px 0;
transition:0s;
}
<li>Style This</li>
the :active rule will stop matching as soon as the mouse button is released. thus the :before will be removed.
You could render the block, and not display it until the :active starts matching.
caveat: If the :before block is clicked, its parent will also become active.
In the end, I would opt for a JavaScript solution.
li {
transition:0s 1s;
}
li:before{
content:"hello !";
z-index:99999999;
position:fixed;
bottom:0px;
width:100%;
background:black;
text-align:center;
color:white;
padding:10px 0;
transition:1s;
opacity:0;
}
li:active:before {
display:block;
opacity:1;
transition:0s;
}
<li>Style This</li>
The trick won't work as you expect simply because there is no transition applied to the li element.
You need first to understand how it works. Here is a simple example:
.box {
background:red;
height:200px;
transition:0s 1s;
}
.box:active {
background:green;
transition:0s;
]
<div class="box"></div>
When you click, the active state is considered; thus the transition is set to 0s and the background become immediately green. When you release the mouse, the active state is no more considered and we have the new transition with a dely so the the background go back to red after this delay.
So in order to have such think, you may consider doing the same but with the pseudo element:
li:before {
content: "hello !";
z-index: 99999999;
position: fixed;
bottom: 0px;
width: 100%;
background: black;
text-align: center;
color: white;
padding: 10px 0;
opacity:0;
transition: 0s 4s;
}
li:active::before{
opacity:1;
transition: 0s;
}
<li>Style This</li>
I considred opacity but it can work with any animatable property.
is there a better way to create this style of "underline" through CSS, other than creating a background image for it?
To be clear, I'm only interested in the "duplicated line" effect, a thicker and shorter line sitting directly atop a thinner and longer line of a different color. Thanks!
You can use pseudo elements here, i.e. :before and :after. Here, what am doing is, using an h1 element which am displaying it as inline-block. Later, we need to use CSS positioning to set both the bottom borders in place, as the borders are smaller than your element.
Later, again by using CSS positioning, we position the small border on top of the bigger one. Note that am using left: 50%; and transform: translateX(-50%) to position the border in horizontally center.
Make sure you don't miss out the z-index as it is important to use here, else the other border will render on top of the smaller one.
#import url('https://fonts.googleapis.com/css?family=Varela+Round');
* {
margin: 0;
padding: 0;
outline: 0;
box-sizing: border-box;
}
h1 {
position: relative;
display: inline-block;
font-family: Varela Round;
font-size: 24px;
text-transform: uppercase;
font-weight: bold;
color: #401f1c;
margin: 40px; /* not required, only for demo purpose */
}
h1 span {
color: #efcc4c;
}
h1:before,
h1:after {
content: '';
position: absolute;
left: 50%;
transform: translateX(-50%);
}
h1:before {
bottom: -11px;
width: 40px;
border-bottom: 3px solid #efcc4c;
z-index: 1;
}
h1:after {
width: 80%;
border-bottom: 1px solid #ddd;
bottom: -10px;
}
<h1>Our <span>Services</span></h1>
Edit: Refactored my code and making the demo more precisee.
Try this
HTML
<div class="text">
<span>our</span>
Services
</div>
CSS
.text{
font-weight:600;
font-size:25px;
color:red;
position: relative;
display:inline-block;
}
.text::after,
.text::before{
content:"";
position: absolute;
left: 0;
right: 0;
bottom: -5px;
margin:auto;
border-radius:5px;
height:0px;
}
.text::before{
width:100%;
border:1px solid #ccc;
}
.text::after{
width:50%;
border:2px solid red;
bottom:-6px;
}
.text span{
color:#000000;
}
Link for reference
hope this helps..
I always create "divider", like:
<div class='divider'>
<div class='divi-1'></div>
<div class='divi-2'></div>
<div class='divi-3'></div>
</div>
CSS:
.divider{
padding-top:15px; //or other
text-align:center;
display:block; // or column in bootstrap like col-md-12
}
.divider .divi-1{
display:inline-block;
height:2px; //or other
width:50px; // or other
background:#e5e5e5;
.
.divider .divi-2{
display:inline-block;
height:2px;
width:50px;
background:#000000;
}
.divider .divi-1{
display:inline-block;
height:2px; //or other
width:50px; // or other
background:#e5e5e5;
}
And that's it. You can also use vertical-align for inline-block so You have some more options to move lines verticaly ... and also it's in the flow so You know what size it have and can be sure that other elements won't overlap it.
Please refer this fiddle , http://jsfiddle.net/shrikanth/79AfQ/
After hovering header(h2), div element(popup) is displayed , which is as per design.
However I can't navigate to new div.(new div gets disappear soon after moving out h2 element)
Is there any fix for this , so that user can click on headrer then can click on contact of another div element?
HTML
<h2>What is CSS?</h2>
<div id="popup">
Contact
</div>
CSS
h2 {
position:relative;
top:22px;
left:44px;
width: 170px;
height:33px;
text-align:center;
}
#popup {
width: 240px;
background: #727272;
padding: 10px;
border-radius: 6px;
color: #FFF;
position: relative;
top:15px;
left:44px;
font-size: 12px;
line-height: 20px;
display:none;
}
h2:hover+ #popup {
display:inline-block;
}
h2:hover {
background-color:green;
}
#popup:before {
content:"";
display: block;
width: 0px;
height: 0px;
border-style: solid;
border-width: 0 15px 15px 15px;
border-color: transparent transparent #727272 transparent;
position: absolute;
top: -15px;
left: 92px;
}
Just change the hover pseudo-selector rule to include the #popup element, too (assuming your goal is just to be able to click the contact link in the #popup)
h2:hover+ #popup, #popup:hover{
display:inline-block;
}
If you want to use this approach, I suggest adding padding to the h2 element to allow your mouse to leave it without immediately deactivating the hover state, or wrapping it with a larger, invisible element.
Another way would be to add the #popup inside the h2 and absolutely position it.
This way, when you're hovering over the popup, you'll be hovering over the h2 as well.
One thing to note here is not to leave any spaces between h2 and the popup, like ReeceJHayward suggested.
<h2>What is CSS?
<div id="popup">
Contact
</div>
</h2>
DEMO:
http://jsfiddle.net/79AfQ/7/
Trying to make arrow link with CSS.
This one works in Firefox, but has a problems in IE and webkit-based browsers with arrowhead's position. Double div used for centering link content. Any suggestions?
content
<a href="#" class="readmore">
<div>
<div>
link content
</div>
</div>
</a>
content
CSS
.readmore {
text-decoration:none;
}
.readmore > div {
display: table;
height: 30px;
//width: 100%;
background: #008a00;
transition: background 0.2s;
}
.readmore > div:hover {
background:orange;
}
.readmore > div::after {
content:"";
display:inline;
position:absolute;
border: 15px solid;
margin-top:-15px;
border-color:transparent transparent transparent #008a00;
transition: border-left-color 0.2s;
}
.readmore > div::before {
content:"";
display:inline-block;
width:6px;
position: static;
background:#008a00;
transition: background 0.2s;
}
.readmore > div:hover::after {
border-left-color:orange;
}
.readmore > div > div {
display: table-cell;
//text-align: center;
vertical-align: middle;
color:white;
}
You should set the top explicitly to 0 for the :after element, and also remember to set the position:relative for the div element so that the absolute positioning works as expected:
.readmore > div::after {
...
top:0;
}
.readmore > div {
...
position:relative;
}
Fiddle
NOTE: The negative margin-top should be removed. The cause of your problem is you use negative margin-top (maybe by trial and error until it looks OK in FF), but the position also depends on the top and left. The default values of these properties are implemented differently by different browsers, the only solution to set it in order is explicitly set the top, left and remember the rule to determine the containing block for the absolute positioned element. (the nearest ancestor which has position as absolute or relative).
Try this code -- >
HTML :
<div>content</div>
Link
<div>content</div>
CSS :
a{
padding:10px;
background:#2ecc71;
display:inline-block;
position:relative;
}
a:hover{
background:orange;
}
a:hover:after{
border-left: 20px solid orange;
}
a:after {
display: inline-block;
content: "";
width: 0;
height: 0;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-left: 20px solid #2ecc71;
position: absolute;
right:-20px;
top:0;
}
JS FIDDLE DEMO
The border width and the right and top positions can be tweaked according to your needs
I'm trying to make custom checkboxes with CSS3, which is working great on Chrome. On Firefox... not so much.
Edit: it seems to be working fine on Firefox 37.
The answer below is still relevant, but the style related issues from mid 2013 are resolved.
IE support isn't mentioned here but edits/answers regarding it are welcome.
demo
The HTML:
<input type="checkbox" id="first"/>
<label for="first">This is pretty awesome</label>
The CSS:
input[type=checkbox] {
appearance: none;
background: transparent;
position: relative;
}
input[type=checkbox]::after {
position: absolute;
top: 0;
left: 0;
content: '';
text-align: center;
background: #aaa;
display: block;
pointer-events: none;
opacity: 1;
color: black;
border: 3px solid black;
}
input[type=checkbox] + label {
line-height: 48px;
margin: 0 15px 0 15px;
}
input[type=checkbox]:hover::after {
content: '';
background: #32cd32;
opacity: .3;
}
input[type=checkbox]:checked::after {
content: '\2713';
background: #32cd32;
}
input[type=checkbox]:checked:hover::after {
opacity: 1;
}
input[type=checkbox],
input[type=checkbox]::after {
width: 48px;
height: 48px;
font-size: 46px;
line-height: 48px;
vertical-align: middle;
border-radius: 50%;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
Note: I removed vendor prefixes, and things like user-select for brevity. The full code is in the pen.
What do I need to change to have it look the same on Firefox as it does on Chrome?
Desired:
Not desired:
You can enable custom styles for checkbox specifically for mozilla browser by adding this property and it worked for me.
-moz-appearance:initial
I managed to fix it as much as seems possible (I'd still love a better solution, if one exists). I switched all of the selectors from
input[type=checkbox]::after
to
input[type=checkbox] + label::after
Downside:
requires a label
But:
HTML requires input elements to have a label
Conclusion:
only bad for invalid HTML
doesnt technically need a LABEL, but does need control over the mark up to ensure there is a target-able sibling immediately after the checkbox.
i.e.
input[type=checkbox] + span::after{
display:block;
width:50px;
height:50px;
background:yellow;
display:block;
}
input[type=checkbox]:checked + span::after{
display:block;
width:50px;
height:50px;
background:yellow;
display:block;
}
<input type="checkbox"></input>
<span class="targetMe"></span>
target the span using the sibling selector and :after elements as above.
Might as well put in a label tho at this point... :P
The problem is that :after and ::after technically create an element as the last child of the element the pseudoselector is applied to. Firefox doesn't like to create children inside of its checkboxes. This is actually part of a bigger topic which is replaced elements.
You will see the same issue with the :before and ::before pseudoelements not working on checkboxes because they would create elements as a first child element within the element being selected.