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
Related
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.
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>
So if I increase the top margin on #featured, it pulls the height from header down with it. What am I doing wrong?
example. if I change #featured {margin:0 auto} to #featured {margin:20px auto}, the white of the header will go down with 20 px, and then show featured. What I want is that #featured gets pulled down 20px and a grey 'border' remains between featured and header
site: http://e2-repair.be/
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
header {
height: 100px;
}
header #header-cont {
width: 1000px;
margin: 0 auto;
height: 100px;
font-family: 'Sofadi One', cursive;
}
header img {
height: 80px;
width: 80px;
float:left;
margin-top:10px;
}
header h1 {
font-size:32px;
float:left;
height:100px;
line-height:100px;
}
header nav{
float: right;
}
header nav ul {
list-style: none;
display: block;
height:100px;
}
header ul li {
display: inline-block;
padding: 0 50px;
}
header ul li a{
text-decoration: none;
color: #990000;
display: block;
height: 100px;
line-height: 100px;
border-top: 3px solid;
border-color: #FFF;
-webkit-transition: border-color .1s linear;
-moz-transition: border-color .1s linear;
-o-transition: border-color .1s linear;
transition: border-color .1s linear;
}
nav ul li a:hover {
border-color: #990000;
}
header a:hover, header a:visited, header a:active {
color: #333;
text-decoration: none;
outline: 0;
}
#content-1 {
height: 400px;
background-color: grey;
}
#featured {
position:relative;
height: 350px;
width: 1000px;
margin: 0 auto;
border:2px solid;
border-radius:5px;
border-color:white;
}
html:
<header>
<div id="header-cont">
<img src="logo.png" alt="Logo" />
<h1>E2 Repair</h1>
<nav>
<ul>
<li>Smartphones</li>
<li>Tablets</li>
<li>Laptops</li>
<li>Desktops</li>
</ul>
</nav>
</div>
</header>
<div id="content-1">
<div id="featured">
fewfwe
</div>
</div>
Add a padding-top inside your #content-1 container instead of adding a margin to its child.
Alternatively, you can add an overflow: auto to the #content-1 contaner, and then the margins applied to its child #featured will work.
The reason why this works like this is due to the fact that two elements margins will join together (collapse) when adjacent. So, the margin applied to the child elements gets really joined with the parent one. This, unless the margins don't touch eachother (which happens if you use a padding): infact, you could as well use:
#content-1 { padding: 1px; }
#featured { margin: 19px auto; }
As long as they are not touching eachother, they will not collapse, so the child element maintains its own margin. From the specs:
The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance.
Source
The overflow: auto has the effect of not making borders collapse (from the above page):
Margins of elements that establish new block formatting contexts (such as floats and elements with 'overflow' other than 'visible') do not collapse with their in-flow children.
You should use padding-top, apply it to content-1 container. Padding will be applied inside the container, however margin will only be applied outside the container. I suggest you to read some articles online for better understanding.
http://html.net/tutorials/css/lesson10.php
I have a div I'm adding appearance: button style to it. This works but it causes a shift in Firefox, I suspect it is because of the border but using box-sizing:border-box doesn't stop it. I also tried adding width and height but it still shifts.
http://jsfiddle.net/2CEuu/2/
<div id="add-new-complaint">
<div class="plus 3"></div>
Add new Complaint
</div>
[id|=add-new]{
display: inline-block;
padding:4px;
cursor:pointer;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
[id|=add-new]:hover{
-webkit-appearance:button;
-moz-appearance:button;
appearance:button;
}
div.plus{
width:15px;
height:15px;
position:relative;
display: inline-block;
}
div.plus::before{
width:100%;
height:33.333%;
top:33.333%;
left:0;
position:absolute;
content:'';
background-color:#789dc3;
}
div.plus::after{
width:33.333%;
height:100%;
top:0;
left:33.333%;
position:absolute;
content:'';
background-color:#789dc3;
}
You can target only Firefox to fix the problem:
#-moz-document url-prefix() {
[id|=add-new]:hover{
padding: 1px;
}
}
Would it work for you?
The way I see it there are 2 solutions,
Either add/reduce padding/margin accordingly on hover to fake the shift back to its position,
like so:
a { margin: 10px 5px; padding: 10px; }
a:hover { padding: 9px 10px 10px 9px; }
Or, better, add a default transparent border:
a { border: 1px solid rgba(0,0,0,0); }
This will keep the box at the correct size until it is hovered.
I'm using the following test code to try create a rhombus type shape. The span is a standard oblong, and the 2 sides will make it appear as a rhombus
**********
* *
******
However, the before and after selectors don't seem to render anything. I'm not sure if I'm doing it wrong or if I'd just be better off positioning them absolutely.
Any ideas?
<style>
span {
width:50px;
height:20px;
color:white;
background-color:red;
padding:10px;
}
span:before {
background: url('left_side.png') left center no-repeat;
height:43px; width:22px;
}
span:after {
background: url('right_side.png') right center no-repeat;
height:43px; width:22px;
}
</style>
<html>
<body>
<span>
Some text goes here
</span>
</body>
</html>
#demo { border-top: 100px solid red;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
height: 0; width: 100px; }
do it without images why people made css3
Demo : http://jsfiddle.net/sahilpopli/dRyLg/
The content property is mandatory, even if left empty :
span:before {
content : "";
display:inline-block;
background: url('left_side.png') left center no-repeat;
height:43px; width:22px;
}
span:after {
content : "";
display:inline-block;
background: url('right_side.png') right center no-repeat;
height:43px; width:22px;
}
Edit : added display:inline-block; for dimension properties to actually work with span, see this example http://jsfiddle.net/3nvhb/
Try this:
span:before {
content: url('left_side.png');
height:43px; width:22px;
}
span:after {
content: url('right_side.png');
height:43px; width:22px;
}