Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
How can I create a 2 color border like this around an image?
Like this:
This is for an HTML website. What CSS should I use? Thanks in advance :)
Fiddle Link
CSS
#mainDiv {
height: 200px;
width: 560px;
position: relative;
border-bottom: 8px solid #f51c40;
background: #3beadc;
border-top: 4px solid yellow;
}
#borderLeftbottom {
border-left: 8px solid #f51c40;
position: absolute;
top: 50%;
bottom: 0;
}
#borderRightbottom{
border-right: 8px solid #f51c40;
position: absolute;
top: 50%;
bottom: 0;
right:0;
}
#borderLefttop {
border-left: 4px solid yellow;
position: absolute;
top: 0;
bottom: 50%;
}
#borderRighttop{
border-right: 4px solid yellow;
position: absolute;
top: 0;
bottom: 50%;
right:0;
}
HTML
<div id="mainDiv"><img src="https://www.google.com/images/srpr/logo11w.png" alt="google" />
<div id="borderLeftbottom"></div>
<div id="borderRightbottom"></div>
<div id="borderLefttop"></div>
<div id="borderRighttop"></div>
</div>
Fully reusable solution for any image - just need to wrap it with a div with class .multipleBorder
FIDDLE
1) Wrap the image in a div.
2) Give the div padding: say 12px - 10px for outer border and 2px for inner border
3) Create pseudo elements :before and :after the div - each with 50% height
4) Set a border and background for each pseudo element (background is used as inner border)
5) Remove the bottom border of the top element and the top border of the bottom element.
Done!
Markup
<div class="multipleBorder">
<img src="http://placehold.it/600x150" alt="" width="600px" height="150px" />
</div>
CSS
.multipleBorder
{
position: relative;
display: inline-block;
padding: 12px;
}
.multipleBorder:before, .multipleBorder:after
{
content: '';
position: absolute;
top:0;
left:0;
width:100%;
height: 50%;
border: 10px solid silver;
border-bottom: none;
background: maroon;
z-index: -1;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.multipleBorder:after
{
bottom:0;
top: auto;
border: 10px solid maroon;
border-top: none;
background: silver;
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
It seems something like this has been addressed before, but most of what I'm finding is for the more generic issue that doesn't pertain to most browsers today. I'm encountering the known IE issue where using border-radius with a border and a background (a color in my case) results in the background bleeding beyond the border.
I'm wondering if there is a workaround that actually can mask this issue... Some of the things I've tried:
<meta http-equiv="X-UA-Compatible" content="IE=10" />
overflow:hidden on the parent
background-clip:border-box
adding .1 to the border-radius
None of these have worked. Is there another workaround (other than "use images") while I wait for yon IE team to fix things?
I've created a fiddle that illustrates this well and documents what I've found in more detail.
I have experienced this before.
I recommend instead styling the border with CSS generated content, in a manner such as this:
.redcircle::after {
content:'';
display:block;
left:0;
top:0;
right:0;
bottom:0;
border-radius:100px;
border:10px solid yellow;
position:absolute;
pointer-events: none; //ensures no clicks propogate if this is desired
}
You can crate an ::before or ::after CSS Pseudo and make your background: red; on them. Set your width, height and border-radius on 100% and for example don't change z-index to -1, you can see his get the inside width and hight and don't bleeding out.
Screenshot from Explorer 9 on Vista
And now for example (how its look without z-index play):
body {
background: white;
}
.bluebox {
background: blue;
width: 200px;
height: 200px;
}
.redcircle {
position: absolute;
left: 140px;
top: 40px;
text-align: center;
height: 100px;
width: 100px;
border-radius: 100px;
font-size: 100px;
line-height: 100px;
color: black;
border: 10px solid yellow;
}
.redcircle::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 100%;
background: red;
}
<div class="bluebox">
<div class="redcircle">
!
</div>
</div>
And this one for using:
body {
background: white;
}
.bluebox {
background: blue;
width: 200px;
height: 200px;
}
.redcircle {
z-index: 1;
position: absolute;
left: 140px;
top: 40px;
text-align: center;
height: 100px;
width: 100px;
border-radius: 100px;
font-size: 100px;
line-height: 100px;
color: black;
border: 10px solid yellow;
}
.redcircle::before {
z-index: -1;
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 100%;
background: red;
}
<div class="bluebox">
<div class="redcircle">
!
</div>
</div>
Fiddle Demo
Borrowing from Zeev's answer, which moves the background-color to a :before or :after (which only substitutes a subpixel gap for a subpixel bleed, and across more browsers), and Phil's answer, which moves the border to an :after (which didn't really fix the problem).
Move the background-color to a :before as suggested by Zeev, but give it padding equal to the border-width minus two (or use calc()). Then give it negative top and left positioning with that same amount.
Then move the border to the :after but give it negative top and left positioning equal to the border-width.
This creates an oversized background and recenters it below the content. Then it creates an oversized border and centers it around the content. You could probably oversize the background to other degrees and get the same result. The point is to make it bigger than the hole inside the border, but smaller than the outside of the border. This, naturally, would fail with thin borders, though.
body {
background: white;
}
.bluebox {
background: blue;
width: 200px;
height: 200px;
}
.redcircle {
z-index: 1;
position: absolute;
left: 150px;
top: 50px;
text-align: center;
height: 100px;
width: 100px;
border-radius: 100px;
font-size: 100px;
line-height: 100px;
color: black;
}
.redcircle::before,
.redcircle::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
}
.redcircle::before {
z-index: -1;
background: red;
top: -8px;
left: -8px;
padding: 8px;
}
.redcircle::after {
top: -10px;
left: -10px;
border: 10px solid yellow;
}
<div class="bluebox">
<div class="redcircle">
!
</div>
</div>
background-clip fixes this issue:
.bluebox {
background-clip: padding-box;
}
Can I achieve a custom CSS border with a button at one end which looks like this
Without url(some image link)?
Note: I want so because when I want to change color, I have to manipulate image.
I have achieved using image JS Fiddle
#stretch {
border-image: url(http://akitech.org/img/border.png) 30 30 stretch;
}
The easiest way is to use CSS pseudo-elements to create the decoration (the circle at the left) and to mask the chamfer at the right of the border (the angle at which the border-right would otherwise meet):
div {
border: 10px solid transparent;
width: 250px;
padding: 10px 20px;
position: relative;
/* this property has to be set to change the border-color: */
border-bottom-color: #f90;
}
/* common shared styles: */
div::before,
div::after {
/* to ensure the pseudo-elements are rendered: */
content: '';
/* for positioning: */
position: absolute;
/* positioning the element with its uppermost edge
against the bottom of the element, against the
upper side of the bottom-border: */
top: 100%;
/* again, set to change the color of the ends: */
background-color: #f90;
}
div::before {
/* position against the left edge: */
left: 0;
/* move the pseudo element 10px up, and
10px left: */
margin: -10px 0 0 -10px;
height: 30px;
width: 30px;
/* making the pseudo-element a circle: */
border-radius: 50%;
}
/* masking the chamfer of the border-bottom's
right-most edge: */
div::after {
left: 100%;
/* making the height/width the same width
as the border itself: */
height: 10px;
width: 10px;
}
div {
border: 10px solid transparent;
width: 250px;
padding: 10px 20px;
position: relative;
border-bottom-color: #f90;
}
div::before,
div::after {
content: '';
position: absolute;
top: 100%;
background-color: #f90;
}
div::before {
left: 0;
margin: -10px 0 0 -10px;
height: 30px;
width: 30px;
border-radius: 50%;
}
div::after {
left: 100%;
height: 10px;
width: 10px;
}
<div id="stretch">Here, the image is stretched to fill the area.</div>
In order to have these borders adapt to the length of the text, either the elements you want to have custom-bordered must themselves be able to contract to the width of the text, either using float:
div {
border: 10px solid transparent;
position: relative;
border-bottom-color: #f90;
padding-left: 20px;
/* forces the element to take up only that space required by
its (non-floated) contents: */
float: left;
/* forces the floated elements to the next line: */
clear: left;
}
div {
border: 10px solid transparent;
position: relative;
border-bottom-color: #f90;
padding-left: 20px;
float: left;
clear: left;
}
div::before,
div::after {
content: '';
position: absolute;
top: 100%;
background-color: #f90;
}
div::before {
left: 0;
margin: -10px 0 0 -10px;
height: 30px;
width: 30px;
border-radius: 50%;
}
div::after {
left: 100%;
height: 10px;
width: 10px;
}
<div>text</div>
<div>longer text</div>
<div>much longer text</div>
<div>much much much longer text</div>
Or, possibly more simply, use display: inline-block:
div {
border: 10px solid transparent;
position: relative;
border-bottom-color: #f90;
padding-left: 20px;
display: inline-block;
}
div {
border: 10px solid transparent;
position: relative;
border-bottom-color: #f90;
padding-left: 20px;
display: inline-block;
}
div::before,
div::after {
content: '';
position: absolute;
top: 100%;
background-color: #f90;
}
div::before {
left: 0;
margin: -10px 0 0 -10px;
height: 30px;
width: 30px;
border-radius: 50%;
}
div::after {
left: 100%;
height: 10px;
width: 10px;
}
<div>text</div>
<div>longer text</div>
<div>much longer text</div>
<div>much much much longer text</div>
Or display: inline (these don't automatically force new-lines between elements, obviously):
div {
border: 10px solid transparent;
position: relative;
border-bottom-color: #f90;
padding-left: 20px;
display: inline;
}
div {
border: 10px solid transparent;
position: relative;
border-bottom-color: #f90;
padding-left: 20px;
display: inline;
}
div::before,
div::after {
content: '';
position: absolute;
top: 100%;
background-color: #f90;
}
div::before {
left: 0;
margin: -10px 0 0 -10px;
height: 30px;
width: 30px;
border-radius: 50%;
}
div::after {
left: 100%;
height: 10px;
width: 10px;
}
<div>text</div>
<div>longer text</div>
<div>much longer text</div>
<div>much much much longer text</div>
summary:
for simplist way to this question, should not using svg, pure css can draw the shape author expected very well cause it's a combination of cycle(border radius)+rect(thicker line), let's refer to the David's answer should be the easiest and most clean way to draw that shape under text.
//below is my debugging history and tries (i searched out many ways to approach it);
//though not good answers
I use background css attribute (not OP wanted) Op used border-image also valid.
<div class="custom-border" >SOME TEXT HERE</div>
<style>
.custom-border{
padding-left:20px;
width:200px;
background:url(http://img1.wikia.nocookie.net/__cb20140224040010/shantae/images/b/bc/HGH_border_bottom.png) 0px 5px no-repeat;
background-size:contain;
height:150px;
}
</style>
later I realized OP might dislike using image traditional way, I re understand the
question is asking how to draw that shape in pure css and place it under the text and the responsive should be as flexible as the traditional way the svg shape will auto strech with the text placed on it.
after that, I've find some way to generate svg and place under text
see if it works for no image solution or you can get it improved based on fiddle
http://jsfiddle.net/hahatey/hsfxS/1464/
during the process, i've found this useful tool of generating svg from below reference url: http://svg-edit.googlecode.com/svn/branches/2.6/editor/svg-editor.html
But the flaw is it's still a fixed width solution, the line svg won't auto stretch.
Have found a unclean way to improve auto stretch though not in pure css responsive way.
but auto strech can be done by dynamically change below line
<rect stroke="#ff0000" id="svg_2" height="8" width="100%" y="27" x="40" stroke-width="5" fill="#FF0000"/>
where width="100%" or fixed value => width="function return value"; //
// during this try, i found a little bug, jquery seems unable to select svg or element inside svg? however svg element tag attribute can be written in backend languge so still valid.
//3.44
Another way without touching the inner "rect' element below "svg" tag, is to add a container to the whole thing, and using function to dynamically
assign width for the container;
like my attempt in this
fiddle: http://jsfiddle.net/hahatey/hsfxS/1468/
so at least the width can be dynamically calculated out by a function to calculate the text length of the upper text so the line will be able to strech if the calculation is accurate enough. There could be other ways to do svg auto strech with the text using pure css if other ppl find it.
Thanks.
5.02// since the author didn't say how complex the content is inside the container,
I've created a demo in pure css triggered effct --- auto strech the shape along with the text above it in below fiddle. but i said it sure has many limitations though looks similar.
http://jsfiddle.net/hahatey/a9z1kyx7/
my upper fiddle is only able to align correctly for singleline auto strech
I'm wondering if complex content (more than one line, there maybe a lot of block,inline mixed tag element inside which increases complexity for alignment) can also use css to do such decoration width auto adjustment without touching javascript or backend language.
I found various examples of how to create triangles using CSS (like this one); all of them are based on creating a 0-sized box and fiddling with borders to create the triangle shape. Ok, very nice.
But how can I actually place something inside such a triangle?
You can use positioning techniques to place some content over the triangle and not under the triangle..
I emphasized over and under because using positioning am positioning the text over the triangle, so triangle element isn't the parent of the content, as to create triangles we use height: 0; and width: 0; so you need to overlay the text.
Just make sure you use position: relative; for parent element holding absolute positioned element.
Didn't used z-index but you can use that to play safe with the stacking order.
Demo
<div class="wrap">
<div class="triangle"></div>
<span>Hello</span>
</div>
div.wrap {
position: relative;
}
div.triangle {
height: 0;
width: 0;
border: 50px solid #f00;
border-top-color: transparent;
border-left-color: transparent;
border-right-color: transparent;
}
div span {
position: absolute;
left: 35px;
bottom: 0;
}
This way can be sloppy but it would work for a basic situation.
http://jsfiddle.net/Yc5nF/1/
<div class="arrow-right">
<p>Foobar</p>
</div>
.arrow-right {
position: relative;
width: 0;
height: 0;
border-left: 150px solid transparent;
border-bottom: 150px solid green;
border-right: 150px solid transparent;
}
.arrow-right p {
position: absolute;
top: 70px;
left: -20px;
}
I have a container that uses inset box shadow. The container contains images and text. The inset shadow apparently does not work on images:
The white section here is the container. It contains a white image, and there is inset box shadow applied to it.
body {
background-color: #000000;
}
main {
position: absolute;
bottom: 0;
right: 0;
width: 90%;
height: 90%;
background-color: #FFFFFF;
box-shadow: inset 3px 3px 10px 0 #000000;
}
<main>
<img src="https://upload.wikimedia.org/wikipedia/commons/d/d2/Solid_white.png">
</main>
Is there a way to make the inset box shadow overlap images?
Just to chime in on this, because I was just creating something similar...
I hate polluting my markup with extra elements for the sake of styling, so the CSS solution is to use the :after pseudo element:
main::after {
box-shadow: inset 3px 3px 10px 0 #000000;
content: '';
display: block;
height: 100%;
position: absolute;
top: 0;
width: 100%;
}
<main>
<img src="https://upload.wikimedia.org/wikipedia/commons/d/d2/Solid_white.png">
</main>
It's probably too late for what you were trying to do, but is the better solution in my estimation.
Because the shadow is part of the parent container it renders below the image. One alternative is to have a div which places a shadow overtop the image like so:
body {
background-color: #BBB;
}
main {
position: absolute;
bottom: 0;
right: 0;
width: 90%;
height: 90%;
background-color: #FFFFFF;
border-radius: 20px;
}
main img {
border-radius: 20px;
}
.shadow {
position: absolute;
width: 100%;
height: 100%;
box-shadow: inset 3px 3px 10px 0 #000000;
border-radius: 20px;
top: 0;
left: 0;
}
<main>
<img src="https://upload.wikimedia.org/wikipedia/commons/d/d2/Solid_white.png" />
<div class="shadow"></div>
</main>
Edit: I've updated the fiddle to include border radius on the shadow and on the img which solves the issue identified in the comments.
The reason it's not overlapping is because the image is inside the div, so the image is on top of it. The image is higher (closer to the user) than the div.
You can change the image to use position: relative; z-index: -1, and have the containing div use a border instead of setting background color on the body. You'll need to use box-sizing: border-box to include the border in the width of the div.
DEMO
body {
background-color: #FFF;
}
main {
position: absolute;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
border: 60px solid black;
box-shadow: inset 3px 3px 10px 0 #000000;
box-sizing: border-box;
}
img {
z-index:-1;
position: relative;
}
For those, who're using absolute-positioned, full-size :before/:after pseudo elements, consider using pointer-events: none on the pseudo-element so the original elements remain clickable.
The best way to achieve this in 2020 would be to use mix blend mode on the image. use the box-shadow on the parent element of the img and use mix-blend-mode: multiply.
You could set the image as the div's background instead:
background-image:url(http://www.placehold.it/500x500)
jsFiddle example
https://stackoverflow.com/a/21415060/6235358
that's a great way to do it but we can do it in a better way using the ::after pseudo-class so you'll not have to add an empty <div> to your HTML
As Rilus mentioned we could use a pseudo class. Unfortunately this does not seem to work on an img tag for some reason however we can use a combination of inner and outer containers to achieve the affect we need.
.outer:hover .inner:after {
position: absolute;
content: '';
color: white;
display:block;
bottom: -0px;
right: -0px;
width: 100%;
height: 100%;
z-index: 11;
border: solid 10px red;
}
http://jsbin.com/kabiwidego/1/
not sure about ie 10 though as it seems to handle pseudo classes that are absolutely positioned slightly differently to most browsers.
One simple fix if you are clever with your decimals is to store your content in a separate div which you then select and implement a certain number of pixels from the top.
For example, let's say your header has a height of 50px. You could begin your #content div id 53.45px from the top (or whatever height your drop shadow is) and then your shadow would appear above the images.
One issue with this is that if you are using a rather transparent shadow, the more transarent it is the more tacky it may look by implementing this css.
In practice the code would be as follows:
HTML:
<header>
Whatever's in your header
</header>
<div id="content>
Page content
</div>
CSS:
header {
height: 50px;
box-shadow: 0 5px 5px rgba(0,0,0,1);
}
#content {
top: 55px;
}
Even if i'm late for the party, I had the same issue these days and worked on a solution. For me, the best solution (mobile friendly) is this one:
JSFiddle:
.image-inset-container {
margin-bottom: 30px;
}
.image-inset-shadow {
position: relative;
}
.image-inset-shadow img {
border-radius: 20px;
}
.image-shadow {
position: absolute;
width: 100%;
height: 100%;
box-shadow: inset 3px 3px 10px 0 #000;
border-radius: 20px;
top: 0;
left: 0;
}
<body>
<h4>Reimagined Web Design</h4>
<p>With your input and business goals in mind, we bring your brand to life through custom human-facing graphics and
visual elements targeted toward your audience for good user experience and created in future-forward technology,
guaranteeing a successful new web design.</p>
<div class="image-inset-container">
<div class="image-inset-shadow"><img src="https://upload.wikimedia.org/wikipedia/commons/d/d2/Solid_white.png" alt="img1" />
<div class="image-shadow"></div>
</div>
</div>
<p>We initiate a collaborative process where your team is involved in every step to create a frictionless and
delightful
experience for your customers. Our designers immerse themselves in your industry and your brand aesthetic to
deliver
a website that represents your business while achieving your goals for a connected future.</p>
</body>
I am having a very hard time understanding what I have to change in order to impact the size of this CSS triangle (as originally defined on this stackoverflow entry). I am looking for the same effect but about 50% smaller triangle.
I noticed in the referenced stackoverflow post #DanielD noted the following:
1) (padding-left + width)/padding-top = (border-left + border-right)/border-top = base/height
2) margin-left = -border-left = -border-right
3) margin-top = -border-top
4) width = padding-left
But when I try to follow this I get completely muddled.
This is the current code I have:
Fiddle
HTML:
<div class="top">
<div class="triangle-down"></div>
</div>
<div class="bottom"></div>
CSS:
.top
{
background: pink;
height: 100px;
position: relative;
}
.bottom
{
background: lightGreen;
height: 100px;
}
.triangle-down{
width: 3%;
height: 0;
padding-left:3%;
padding-top: 2%;
overflow: hidden;
position: absolute;
left:0;right:0;
margin:auto;
top: 100px;
z-index:1;
}
.triangle-down:before {
content: '';
display: block;
width: 0;
height: 0;
margin-left:-50px;
margin-top:-33px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-top: 33px solid pink;
}
If you change: padding-left:1.5%;
padding-top: 1%; within the triangle-down it should change the size to half of what you originally had.
Updated Fiddle to also change width: 1.5%;
I hope this is what you were looking for.
Try this
Since the triangle is made solely of borders, you have to affect each of the borders of the :after elements. Then you have to compensate for the change in size by changing the margin-top and margin-left values
.triangle-down:before {
content: '';
display: block;
width: 0;
height: 0;
margin-left:-25px;
margin-top:-25px;
border-left: 25px solid transparent;
border-right: 25px solid transparent;
border-top: 25px solid pink;
}