CSS Border Overlapped By Child Element - css

See here:
http://jsfiddle.net/cnJ6q/
I can't just add the border to the child element, it needs to be added to the parent (.dc-slick) - Is there any way to fix this? Z-index does not seem to help.
Thanks.

The child div will inherit its parent's z-index no matter what you use.
The problem here is mismatching border-radiuses. Use the same border radius on each element, otherwise you will get this overlap.
border-bottom-left-radius: 30px 30px;
border-bottom-right-radius: 30px 30px;
Updated example.

There are 2 ways of doing it. 1) Child element takes the same size as not-transformed parent element. Then background you should cast on parent element
.dc-slick {
border: 3px solid red;
right: 0px;
left: 0px;
position: fixed;
border-bottom-left-radius: 30px 30px;
border-bottom-right-radius: 30px 30px;
z-index: 10001;
margin-top: 0px;
background: black;
}
.dc-slick-content {
color:white;
z-index:9999;
width: 100%;
height: 200px;
border-bottom-left-radius: 15px 15px;
border-bottom-right-radius: 15px 15px;
}
2) You should scale child approximately in same way as parent.
.dc-slick {
border: 3px solid red;
right: 0px;
left: 0px;
position: fixed;
border-bottom-left-radius: 30px 30px;
border-bottom-right-radius: 30px 30px;
z-index: 10001;
margin-top: 0px;
}
.dc-slick-content {
background: black;
color:white;
z-index:9999;
width: 100%;
height: 200px;
border-bottom-left-radius: 28px 28px;
border-bottom-right-radius: 28px 28px;
}

You should have the background color and the border on the same element, so move the background: black to .dc-slick
.dc-slick {
background: black;
}
.dc-slick-content {
/*background: black;*/
/*border-bottom-left-radius: 15px 15px;*/
/*border-bottom-right-radius: 15px 15px;*/
}
Updated JSFidle: http://jsfiddle.net/RxyRV/

Well, it is actually possible.
To bring the child element behind the parent border,
make the child relatively (position: relative) (or absolutely (position: absolute) , if this is already used) positioned and give a negative z-index.
This also works with border-images, where it is very useful if you want to achieve a partially obscuring border image effect:
.container,
.inner {
width: 200px;
height: 200px;
}
.container {
/* from #https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Backgrounds_and_Borders/Border-image_generator */
border-image: url("https://mdn.github.io/css-examples/tools/border-image-generator/border-image-1.png") 27 / 20px / 0px stretch;
border-style: solid;
}
.inner {
background: rgba(0, 0, 0, 0.75);
}
.inner-2 {
position: relative;
z-index: -1;
}
<div class="container">
<div class="inner inner-1">
Test 1, child element above parent border.
</div>
</div>
<div class="container">
<div class="inner inner-2">
Test 2, child element behind parent border.
</div>
</div>
The downside to this technique is that the child element with negative z-index doesn't get JavaScript mouse/touch events. This is something I have to find out as I use this technique for a slider where these events are used.

Related

Border radius and background clip not working as expected on pseudo element

I'm trying to create a button that has many layers - consequently I'm having to make use of pseudo elements.
To clarify, my button is actually an anchor <a>.
I've run into an issue with one of the pseudo elements. I'm trying to give it a background while retaining a touchable target outside of the background. In order to do this, I've applied a background-clip over the content.
Everything works apart from the corners, which are applied but just not the shape I was expecting.
Button 2 is the design I'm trying to crack - by ensuring the pseudo perfectly overlays the element.
I now think I know what is happening but don't know why and how to fix it.
The padding is 6px deep, the border radius 10px. The radius is being calculated as 4px deep and 10px wide.
Any advice appreciated.
div {
margin-bottom: 20px;
}
a, a::before {
box-sizing: border-box;
}
a {
background-color: red;
border-radius: 10px;
color: white;
display: inline-block;
height: 36px;
line-height: 36px;
min-width: 100px;
position: relative;
text-align: center;
z-index: 1;
}
a::before {
background-color: rgba(0, 255, 0, 0.5);
border-radius: 10px;
content: "";
display: block;
height: 48px;
padding: 6px 0;
position: absolute;
top: -6px;
left: 0;
width: 100%;
z-index: -1;
}
.button2::before, .button2a::before {
background-clip: content-box;
}
.button2a {
margin-left: 20px;
}
.button2a::before {
background-color: blue;
}
.button3::before {
background-clip: content-box;
border-radius: 50%;
}
<div>
<p>This is a button with no background-clip - border-radius applied as expected<p>
<p><a class="button1">button 1</a></p>
</div>
<div>
<p>This has same border-radius as above, but background-clip applied on content - overlay doesn't completely disappear - leaves odd shapes at corners as can be seen on blue button. I was expecting 10px corners to mirror center</p>
<p><a class="button2">button 2</a><a class="button2a">button 2</a></p>
</div>
<div>
<p>This has same background-clip applied but uses a percentage for border-radius - seems to work as expected</p>
<p><a class="button3">button 3</a></p>
</div>
I'm trying to create a button that has many layers
What about doing things differently and instead of using pseudo element you can rely on multiple background to have multiple layers:
a.button1 {
background:
linear-gradient(to right,transparent 50%,blue 0),
linear-gradient(to bottom,orange 50%,transparent 0),
red;
border-radius: 10px;
color: white;
display: inline-block;
height: 36px;
line-height: 36px;
min-width: 100px;
text-align: center;
}
<a class="button1">button 1</a>

CSS Border with a botton

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.

Why doesn't inset box-shadow work over images?

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>

putting a inset box shadow on an image or image within a div

I have an image on my page which i want to put an inset box shadow on.
I have tried doing this with the image both in, and out, of a div.
Can anyone help me to get an inset box shadow to display?
HTML:
<body>
<div id="logo">
<img src="images/key.jpg" width="3%" height="3%"/>
</div>
Next
Back
<img src="images/scene1.jpg" width="650" height="650" class="backing"/>
</body>
</html>
CSS
.backing {
position:relative;
z-index:-10;
float:left;
margin-left:12%;
box-shadow: 0 0 -50px -50px #FFF;
-moz-box-shadow: 0 0 -50px -50px #FFF;
-webkit-box-shadow: 0 0 -50px -50px #FFF;
}
.next {
position:relative;
margin-left:8%;
z-index:200;
}
.back {
position:relative;
margin-left:2%;
z-index:220;
}
Box-shadow inset will not work on image, you need to create a div and give box-shadow to that div and put image inside that div.
You can also use a negative z-index on the img element, and use the box-shadow with inset value on the div element.
div {
position: relative; /* Not required now */
margin: 10px;
float: left;
box-shadow: inset 0 0 12px blue;
border-radius: 50%;
}
div img {
display: block;
height: 100px;
width: 100px;
border-radius: 50%;
position: relative;
z-index: -1;
}
Demo
Most of the solutions posted here have problems with the parent elements, a simple solution to this, is using pseudo elements:
.box-shadow
{
background-color: #fff;
height: 235px;
margin: 32px 24px;
text-align: center;
width: 500px;
position: relative;
border-radius: 50%;
overflow: hidden;
}
.box-shadow::after
{
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
-webkit-box-shadow: inset 0 0 10px 10px #000;
-moz-box-shadow: inset 0 0 10px 10px #000;
box-shadow: inset 0 0 10px 10px #000;
border-radius: 50%;
overflow: hidden;
}
<div class="box-shadow">
<img src="http://www.google.com/logos/2012/addams11-hp.jpg" />
</div>
The other answers that propose z-index have an issue if put into context, in my case the image disappeared behind the main div. Preventing this involves setting z-index: 1; (and non static position) to all of the ancestor elements, which is problematic, and may break a lot of existing layout.
I found a clean solution that doesn't require having to touch all ancestor elements.
I finally figured it out with the help of Understanding z-index - The Stacking Context
HTML
The markup stays like this:
<div class="box-shadow">
<img src="/images/graphic.jpg" />
</div>
The challenge is to put the wrapper div and the image into a single stacking context. For this you have to apply styles to the parent element.
Stacking Context CSS
According to the linked article, the following elements create a stacking context:
the root element (HTML),
positioned (absolutely or relatively) with a z-index value other than "auto",
a flex item with a z-index value other than "auto",
elements with an opacity value less than 1. (See the specification for opacity),
elements with a transform value other than "none",
elements with a mix-blend-mode value other than "normal",
elements with isolation set to "isolate",
on mobile WebKit and Chrome 22+, position: fixed always creates a new stacking context, even when z-index is "auto"
specifing any attribute above in will-change even you don't write themselves directly
If we focus on the options that make sense for this use case, we have these alternatives, assuming the parent element of the .box-shadow element is #parent:
1. Positioning and z-index:
This is what I would choose if possible:
#parent {
position: relative;
z-index: 0;
}
2. Opacity
If the parent element needs to have a different position attribute or adding z-index has unwanted side effects, you can use an opacity value that's almost 1, so that it has no visible effect but still creates a stacking context:
#parent {
opacity: 0.999;
}
Finally, the shadow CSS
Then you can apply the shadow on the div and move the img behind it with z-index:
.box-shadow {
box-shadow: 0 0 10px 6px white inset;
}
.box-shadow img {
display: block;
position: relative;
z-index: -1;
}
Here’s a clean, simple and modern approach of CSS pseudo-elements to place a box shadow “on top of an image”, since img tags themselves don’t support pseudo-elements.
HTML:
<div class="box-shadow">
<img src="http://i.stack.imgur.com/8LzBY.jpg" />
</div>
CSS:
.box-shadow {
position: relative;
text-align: center;
}
.box-shadow::after {
box-shadow: inset 0 0 10px 10px #000;
bottom: 0;
content: "";
display: block;
left: 0;
height: 100%;
position: absolute;
right: 0;
top: 0;
width: 100%;
}
.box-shadow img {
max-width: 100%;
width: auto;
}
View the accompanying JSFiddle.
.backing {
position:relative;
z-index:-10;
float:left;
margin-left:12%;
box-shadow: inset 0 0 50px 50px #FFF;
-moz-box-shadow: inset 0 0 50px 50px #FFF;
-webkit-box-shadow: inset 0 0 50px 50px #FFF;
}
.next {
position:relative;
margin-left:8%;
z-index:200;
}
.back {
position:relative;
margin-left:2%;
z-index:220;
}
<div id="logo">
<img src="//picsum.photos/100" width="3%" height="3%"/>
</div>
Next
Back
<img src="//picsum.photos/650" width="650" height="650" class="backing"/>

Nested div vertical align problem

I am trying to vertically center one div (containing a search bar) inside another (a top banner). I was under the impression that to do so you did the following:
#banner {
height: 35px;
width: 100%;
}
#searchbar {
height: 15px;
position: relative;
top: 50%;
margin-top: -7.5px; /* half of the height */
}
This works fine until you add the margin-top at which point it is applied to the #banner as well.
Is there an alternative way to do this, or am I just doing it wrong?
Here's a jsFiddle of my actual code.
I use line-height with the value being the same as height of parent div.
As seen here: http://jsfiddle.net/vkJ78/24/
CSS:
#banner {
background-color: #770E17;
height: 35px;
width: 100%;
border-bottom: 1px solid #333;
}
#src {
width: 300px;
height: 15px;
border: 1px solid #333;
padding: 3px;
}
#srcdiv {
width: 308px;
margin: 0px auto;
position: relative;
line-height: 35px;
}
EDIT: Per recommendation from NGLN, this will also fix horizontal centering, #srcdiv and #src having equal widths.
You have to add overflow: hidden to #banner. To clear the float, I guess.
Then, modify the negative margin to margin-top: -11px in #srcdiv (you have to sum the div height, the border, and the padding for the total height)
http://jsfiddle.net/vkJ78/1/
Give margin:0px and padding:0px and remove margin-top
body {
margin:0px;
padding:0px;
}

Resources