Creating a triangle out of div with css logic explanation? [duplicate] - html

This question already has answers here:
How do CSS triangles work?
(23 answers)
Closed 7 years ago.
I recently worked on creating an element with some text inside it, but it has to be flag based shaped. I googled and found below nice css to achieve it. They basically created small triangles out of div(pointing to left/right/top/bottom) using css and attaching it with adjacent div.
However,I did not find any answers with the logic mentioned thus making me little confused about the triangle creation out of div using CSS.
I wanted to know how that css works, specifically for arrow-left class used below.
HTML:
<div class='element'>
<p>OFFER</p>
<div class="arrow-left"></div>
</div>
CSS:
.element{
background-color:#E47911;
display:inline-block;
position:relative;
padding:2px 15px 2px 10px;
color:white;
line-height:18px;
}
p{
font-size:10px;
margin:0;
}
.arrow-left {
width: 0;
height: 0;
border-top: 11px solid transparent;
border-bottom: 11px solid transparent;
border-right: 11px solid white;
display:inline-block;
position:absolute;
top:0px;
right:0px;
}
Here's the codepen link: http://codepen.io/anon/pen/JGvBpN
Any pointers is much appreciated! Thanks.

It doesn't create a triangle so much as it appears to given how border intersections are rendered at an angle.
.arrow-left {
width: 0; /* unnecessary, but does override any unexpected width */
height: 0; /* unnecessary, but does override any unexpected height */
/* These set up the intersecting borders, set each one to a different color to see the borders forming the "triangle" e.g. red, green, blue */
border-top: 11px solid transparent;
border-bottom: 11px solid transparent;
border-right: 11px solid white;
display:inline-block; /* unnecessary, you're taking the elemtn out of the document flow when you absolute potiion it and the div id a block level element anyway, but to correctly have a border you'll need this so it's a decent safeguard */
/* this takes the element out of the document flow and positions it absolutely within the nearest positioning parent, in this case, the relatively positioned parent */
position:absolute;
/* this moves it to the top right edges of the positioning parent*/
top:0px;
right:0px;
}
Here'es an illustration of the box in chrome's dev tools, pulled out of position to make the effect of what's going on made more obvious:
And here it is with positioning restored:
Note that the part you think is transparent is actually opaque so this isn't masking any part of the orange checkout block; it would be obvious that you drew a white part there if the background of the underlying page were not also white.
For what it's worth, it may be worth looking into using an image or SVG and CSS masking to actually "cut" part of the button out, but you'll need to check the user agent support for your needs or try some work arounds.

Related

How to Apply border to all the elements [on hover] of facebook's page without disrupting the entire page's look and feel

Before flagging this as already asked, pls read the whole scenario. Thanks
SHORT VERSION :
Just to clearly state what i am trying to achieve, here's the page https://www.facebook.com/MercedesBenzPolska/ and I want to add border to the target element (on which i am hovering), whether it be <div> or <img> or <p>, without the shaking
DETAILED VERSION
Webpage in question: Any of Facebook's page.
Requirement: Moving a cursor over an element should add border to the target element [only on hover therefore temporary border not permanent]. Permanent border will be added ONLY if I click on that element. [Simply, if I hover over an element it will be highlighted with, say, pink border and only when i click on it, a green border would be added]
Initial problem: adding border on elements on hover would make the whole page's structure shaky, since I am constantly adding and removing the border. For that what I did was add a transparent 1 px border to all the elements of the page, and on hover just change the color of the border from transparent to pink; thus no shaky.
Present problem: The above solution was working for all the pages till I encountered Facebook's page. It turns out adding the initial 1 px border totally disrupts the structure i.e. the look and feel of the page. DIVs move from somewhere to somewhere else.
How do I now solve my original problem? Is there a way of, maybe like, applying a negative margin or border, so that adding the extra 1 px border does not dirupt the page's structure? I don't know I am just suggesting. Pls help
[SCREENSHOTS]
1. this is when the page loads [without applying the border]
2. Now when I hover over the div containing image ie adding 1 px border on hover, the divs move here and there
css I am using
* { border: 1px solid transparent !important;} //when page loads
.hover-selected{ border: 1px solid #e42a78 !important;} //on hover border
.option-selected:hover { border: 3px solid #529c56 !important;cursor: default;} //when option is selected
The images and the css both reflect towards the same problem, the default 1px transparent border disrupts the page's css and If I don't do that, the on hover border application becomes shaky and the page's css anyway gets disrupt
box-shadow: 0px 0px 0px 1px #000;
Use box shadow instead border. Box-shadow don't take up space.
div {
width:300px;
height:300px;
background: red;
}
div:hover {
box-shadow: 0px 0px 0px 1px #000 inset;
}
<div> Test </div>
outline is perfect for this. It works in a very similar way to border but does not effect layout at all.
div:hover {
outline: 1px solid orange;
}
<div>
Lorem ipsum sit amet.
</div>
<div>
<img src="https://placehold.it/200x100">
</div>
<div>
Lorem ipsum sit amet.
</div>
you can use box-sizing property in css. Try below code with and without box-sizing property
<div class="item">
</div>
.item {
box-sizing: border-box;
height: 50px;
width:50px;
background:red;
}
.item:hover{
border:1px solid black;
}
I would start from something like this and move from there:
*:hover:last-child:before {
display:block;
content:"";
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
border:2px solid red !important;
}
Using a pseudo-element instead of putting a border on the actual object might not create as many issues with the initial layout. Still not exactly what you asked for, but I believe it's at least a bit closer. :-)
EDIT
I believe that the only way to achieve this as good as possible would be to be less greedy when selecting elements in the CSS, and specify a list like so:
a:hover:before,
img:hover:before{
display:block !important;
content:"" !important;
position:absolute !important;
top:0 !important;
bottom:0 !important;
left:0 !important;
right:0 !important;
border:2px solid red !important;
}

input text with icon on the left and border [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm still newbie in html. How can I achieve this with style:
rounded border 1px color grey
icon on the left with peach background
input text on the right
The only way to achieve that as Crossbrowser solution is to use background-image with background-position and background-size
input[type=text]{
background-image: url(http://i.imgur.com/EitD5gR.png);
background-size: 16px 16px;
background-repeat: no-repeat;
background-position: left top;
border-radius: 6px;/*rounded border */
border: 1px solid grey;
padding-left: 16px
}
<input type=text />
in a near future you will be able to do that using :pseudo-element
Its better If you can provide some code but since you are a beginner hope this code helps you
<div id = 'outer'>
<div id = 'inner'>
img
</div>
</div>
CSS
#outer{
width:200px;
height:50px;
border: 2px solid gray;
position:absolute;
border-radius:10px;
}
#inner{
position:relative;
width: 20%;
height:100%;
background-color: yellow;
border-radius:2px;
z-index:-30;
}
Cick for fiddle Fiddle
Here's the basic idea:
The rounded border you'll get with the CSS property border-radius. You'll need to look this up, because not all browsers respect plain ol' border-radius - you'll end up with several css rules (e.g. border-radius:...; -webkit-border-radius:...). The border color you'll get with the css property border-color. http://www.w3schools.com/cssref/pr_border.asp (and the links in the left sidebar) is a good resource to learn about styling borders
The image inside the input is going to be kinda complicated for a newbie. There are a couple ways you could do this… I recommend using a :before "pseudoelement." You'll set the <input> (or whatever the main element you're styling here is) to let elements inside it position themselves relative to it, and then you'll set the pseudoelement to be absolutely positioned all the way on the left. The pseudoelement then gets a specific size, and you put an image into it.
Without doing too much of the work for you, the CSS will be something like
input {
border-radius: ...;
border-color: ...;
position: relative; <-- lets us position child elements relative to this one
}
input:before {
content: url(path/to/the/image);
position: absolute;
left: 0;
width: 30px; <-- I'm just guestimating that number
height: 100%; <--- depending on the rest of your css, this might need to be set in pixels
}
Other problems you might run into:
You might lose the rounded corners on the left. If so, you can round only those corners on the input:before (a tool like http://border-radius.com/ will help you round only certain corners)
If you're using an <input>, it might look wrong in some browsers. That's because browsers supply default styles for inputs. This gets into fancier stuff, so I'll give you the solution up front and you can study up to figure out what it does
input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: 0;
border-repeat: repeat;
}

Multiple borders around a div with a transparent layer

I am trying to create a button with 3 layers of border around it with the middle layer showing the background of the containing div. Examples are worth a thousand words so here you go
http://jsfiddle.net/e5Sxt/2/
html
<div id="content">
<p>Generic Content</p>
<button class="button">Search</button>
</div>
css
#content{
width: 500px;
height: 500px;
background-color: black;
padding: 50px;
color: white;
}
button{
margin-top: 50px;
padding: 20px;
text-align: center;
background-color: #333;
box-shadow: 0 0 0 5px #666, 0 0 0 10px red, 0 0 0 15px #bbb;
border: none;
cursor: pointer;
}
The red box-shadow is where the black of the containing div should come through. If the box-shadow is set to transparent for this layer, the box-shadow under it shows through instead.
I have tried utilizing outlines, borders, and box-shadows to no avail so far. As of right now, I think I will have to wrap the button in another div with the outer border and a padding to show the background, but wanted to see if anyone could do this without adding another html element.
Thanks!
The answer depends on what browsers you need to support (and whether you'd be happy with a fall-back solution for older browsers).
There is a CSS feature called border-image, which, frankly, can do pretty much anything you could think of for a border. You could achieve this effect very easily using this style.
With border-image, you could simply specify a small image with your two colours and transparent middle section. Job done.
Learn more about border image here: http://css-tricks.com/understanding-border-image/
However... there is a big down-side: browser support. border-image is a relatively new addition to the CSS spec. Firefox and Chrome users should be okay, but IE users miss out -- this feature didn't even make it into IE10.
Full browser support details can be found here: http://caniuse.com/#search=border-image
If poor browser support for border-image is enough to kill that idea for you, then another viable answer would be to use :before or :after CSS selectors to create an pseudo-element sitting behind the main element. This would have a transparent background and be sized slightly larger than the main element and with it's own border. This will give the appearance of the triple border you're looking for.
Of course, you can only use this solution if you aren't already using :before and :after for something else.
Hope that gives you some ideas.
I think the only way to do this is by using a wrapper unfortunately. I'm not sure if it is possible to get the transparency through the button background.
Although, if you know the background color, you can use that in the border obviously, but of course this won't work for background gradients.
Here is a proposed jsFiddle showing knowing the color, and another using a wrapper:
http://jsfiddle.net/eD6xy/
HTML:
<div class="box one-div">(1 div, know color)</div>
<div class="two-div">
<div class="box">(2 divs, pure transparent)</div>
</div>
CSS:
/*
With one div, works fine with a constant color (#abc)
But with gradient, probably won't match up correctly
*/
.one-div {
margin: 15px 10px;
border: 5px solid blue;
box-shadow: 0 0 0 5px #abc,
0 0 0 10px red;
}
.two-div {
margin-top: 30px;
padding: 5px;
border: 5px solid red;
}
.two-div > .box {
border: 5px solid blue;
}

Inserting multiple lines into a border in CSS?

I have a page where I want the border to home more than one line.
h2.bord
{
border-style:inset;
border-width:8px;
border-color:green;
background-color:black;
color:white;
text-align:center;
}
This (when used) displays a border around the text.
However,
I want to home more than I one line in this border.
Help?
use a div with border and inside that place this h2 bord
Is border-style:double; what you are looking for?
Alternatively, if you wanted more than a double border's, or borders of multiple styles you could use multiple nested divs, e.g.
<style>
.inset-border { border: 4px inset Black; }
.double-border { border: 4px double Black; }
</style>
<div class="inset-border">
<div class="double-border">
<h2>content</h2>
</div>
</div>
Standard CSS borders only support at the very most a double line (see #Jaimal's answer).
If you need more than that, you need to try the following:
Additional markup: ie more container elements, each with their own border.
Use :before and :after and give them a border. Done right, they should wrap around the original box and give you extra borders. Won't work in IE6 or IE7.
Use the outline property in addition to the border. Outline works very similarly to border, but does have some slight differences. It can give you a third border box though, if used in addition to border-style:double;. Note that it might not work in older browsers.
CSS3 border-image. Using this, you can define your own graphics for the border, which means you can define as many lines as you like. Note: this definitely won't work in older browsers; it's only a fairly recent addition to CSS.
Use background-image to fake it. If you know the size of your box, this might be the simplest and most cross-browser compatible way to do it. Not so useful if you don't know the size of the box in advance though.
Hope that helps.
I'm assuming you're trying to achieve an 3d/'raised' type of border; if that's so, then you could simply use the border-style: groove: JS Fiddle demo.
However, if you're able, you could use the ::after pseudo-element, and an outset border-style:
h2.bord {
border-style:inset;
border-width:8px;
border-color:green;
background-color:black;
color:white;
text-align:center;
position: relative; /* in order to position the pseudo element relative to the parent */
margin: 8px; /* to move the edges of the element from the container element in order to see the borders of the pseudo-element */
}
h2.bord::after {
content: '';
position: absolute;
top: -16px;
left:-16px;
right: -16px;
bottom: -16px;
border: 8px outset green;
}
​JS Fiddle demo.

Background fill shape with text on top using CSS

Right now we have a web page with a bunch of link sections on one page. Each section has a header like so:
This header background is actually two images. The first is just a rectangle and the second has the slanted side on it. As I was looking at this solution, I was wondering if I could solve this with CSS instead of images. While I am not a CSS guru, I did look at a number of examples and was able to get something similar working. However, when I attempt to put text on top of the background, it ends up above the color instead of inside it. The CSS I have also has a fixed size, which is less than idea. I would rather specify a percentage of the available area and have it fill in the color.
Here is the code I've been working with:
<STYLE type="text/css">
.mini_banner
{
display:inline;
border-bottom:30px solid blue;
border-left:0px solid transparent;
border-right:30px solid transparent;
}
</STYLE>
I wanted to apply this to a cell in a table. I also don't want to break compatibility with modern browsers. My "customers" (mostly internal people) are going to be primarily on IE8 or later but I don't want to limit myself if I can help it.
So first, is this possible? Second, how would I accomplish this? And third, is there a way to make it relative in scale instead of fixed?
I would say that you'll have less headaches all the way around if you revert to using a single background image - in this case, a white image with the notch cut out (a PNG-24 with alpha transparency). Make it bigger than you think you need by about 200%, then do something like this:
.minibanner {
background: blue url(..images/notch.png) no-repeat middle right;
font-size: 1.5em;
}
The reason is that relying on border sizes may result in some whackiness across browsers, and it will definitely look weird if any element runs to two lines.
If you make the notch image 200-300% larger, but vertically align it in the middle of the background, and you do increase the font-size, the box will grow, but your white notch will grow right along with it.
UPDATE:
The only other way I can see pulling this off is to add a non-semantic element, such as a or something similar, after your text:
<div>
<p>Hello text</p>
<span></span>
</div>
Then in your CSS:
p {
background: blue;
color: white;
float: left;
padding: 0 20px;
height: 50px;
margin:0;
line-height: 50px;
}
span {
width: 0;
height: 0;
border-top: 50px solid transparent;
border-bottom: 0px solid transparent;
display: inline-block;
border-left: 50px solid blue;
}
See this JSFiddle.
The shape is based on this tutorial on CSS triangles. Now, I've only tried this on a webkit based browser, and it works. You will have to adjust the heights every time you want to change font size, so that is a drawback.
I made it work without an extra span: jsFiddle
.mini_banner
{
width:18em; height:1.5em;
color:white; font-weight:bold; padding-left:0.5em;
margin-bottom:.5em;
}
.mini_banner:before {
display:inline-block; content:''; overflow:hidden;
width:17em; height:0;
margin-bottom:-1.5em; margin-left:-.5em;
border-bottom:1.5em solid blue;
border-right:1.5em solid transparent;
}
Tested in FF, Safari, Opera and IE. (Works in IE8, but not in IE7)