I have a filled circle and a child element. I want the child ele to be 'attached' to the circle on the left. But I don't want this ele to have a visible border on its right edge.
I'm not sure why, but when these two eles are overlapped, the child ele has this faint kind of dashed border on the right.
body {
height: 900px;
width: 1600px;
zoom: 500%;
}
.container {
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
.circle {
position: absolute;
/* border: solid 3px black; */
background: yellow;
width: 300px;
height: 300px;
border-radius: 100%;
display: flex;
align-items: center;
}
.arc {
position: absolute;
width: 29%;
height: 25%;
background-color: yellow;
transform: translate(-68%, 15%) rotate(-24deg);
border-radius: 100% 0% 0% 100%;
/* Changing the last num to 0 gets rid
of the phantom border..? */
border-width: 3px 0px 3px 3px;
border-color: black;
border-style: solid;
/* Padding 1px works to get rid of it when the element isnt rotated */
padding: 1px;
}
<div class="container">
<div class="circle">
<div class="arc"></div>
</div>
</div>
https://codepen.io/CoreyBuckley/pen/ZEWKMaZ
Help on why this is occurring and how to get rid of it is much appreciated!
If nothing else works hide it indirectly with a pseudo element, matching the colour at the edge seems to sort out what appears to be an aliasing problem Edit: I checked setting DPI scaling to 100% it doesnt appear to be linked with that.
.arc:before {
content: ' ';
display: block;
position: absolute;
right: 0;
top: 0;
width: 1px;
height: 100%;
background-color: yellow;
}
Related
I'm trying to use backdrop-filter(blur in this case) on a div only to discover the overflow: hidden property prevents it from applying. The browser is Chrome 78.
Say I've got a div.filter inside a div.block that's wrapper inside a div.container.
div.container > div.block > div.filter
If I apply overflow: hidden to both .container and .block the effect of the filter suddenly disappears. Furthermore, other properties of the .block prevents the filter from being applied.
Seems like the overflow: hidden on .container triggers this erratic behavior. Do you guys have any idea what's going on here?
Demo here: https://codepen.io/marcel_pi/pen/VwYvmGv
Please check the code below:
.container{
overflow: hidden; /* delete to resume normal behavior */
border-radius: 20px;
}
.block{
width: 400px;
height: 400px;
border: 4px solid black;
background: linear-gradient(90deg, transparent 50%, rgba(152,47,138,.5) 50%) antiquewhite;
background-size: 30px;
font-weight: bold;
/* the properties below prevent the filter from being applied once the overflow: hidden is applied to .container */
border-radius: 20px; /* delete to resume normal behavior */
overflow: hidden; /* delete to resume normal behavior */
position: relative; /* delete to resume normal behavior */
}
.filter{
position: absolute;
top: 0;
left: 205px;
width: 230px;
height: 230px;
background: #42add77d;
backdrop-filter: blur(6px); /* the blur filter */
border-radius: 20px;
}
<div class="container">
<div class="block">
<div class="filter"></div>
</div>
</div>
If you apply a filter (0px) to the same element that you apply the overflow property to, it will work.
.container{
overflow: hidden; /* delete to resume normal behavior */
border-radius: 20px;
}
.block{
width: 400px;
height: 400px;
border: 4px solid black;
background: linear-gradient(90deg, transparent 50%, rgba(152,47,138,.5) 50%) antiquewhite;
background-size: 30px;
font-weight: bold;
/* the properties below prevent the filter from being applied once the overflow: hidden is applied to .container */
-webkit-filter: blur(0px);
border-radius: 20px; /* delete to resume normal behavior */
overflow: hidden; /* delete to resume normal behavior */
position: relative; /* delete to resume normal behavior */
}
.filter{
position: absolute;
top: 0px;
left: 205px;
width: 230px;
height: 230px;
background: #42add77d;
backdrop-filter: blur(4px);
border-radius: 20px;
}
<div class="container">
<div class="block">
<div class="filter"></div>
</div>
</div>
You can test it here as well..
It's a stacking order issue. If you do a simple test of adding, z-index to your block element, you'll see the filter working as expected.
I did a little digging around about overflow and how it's properties affect stacking order, but couldn't find any conclusive documentation.
That said, just add z-index: 1 to your block.
Caveat: This will not work on Firefox unless you set the layout.css.backdrop-filter.enabled preference to true in about:config.
https://caniuse.com/#search=backdrop-filter
.container {
overflow: hidden;
/* delete to resume normal behavior */
border-radius: 20px;
}
.block {
width: 400px;
height: 400px;
border: 4px solid black;
background: linear-gradient(90deg, transparent 50%, rgba(152, 47, 138, .5) 50%) antiquewhite;
background-size: 30px;
font-weight: bold;
border-radius: 20px;
overflow: hidden;
position: relative;
z-index: 1;
}
.filter {
position: absolute;
top: 0px;
left: 205px;
width: 230px;
height: 230px;
background: #42add77d;
backdrop-filter: blur(4px);
border-radius: 20px;
z-index: 10;
}
<div class="container">
<div class="block">
<div class="filter"></div>
</div>
</div>
There were some bugs in Chrome with filter / backdrop-filter, border-radius and overflow: hidden:
Asked in May 2013 (Chrome 27): webkit-filter breaks overflow: hidden
Asked in April 2016: Backdrop Filter extends beyond Border Radius.
Should be fixed already: https://bugs.webkit.org/show_bug.cgi?id=142662.
For me, the only property that is not working is .block's overflow: hidden, but you can just remove it, position .filter so that it doesn't overflow and apply its border-radius only to the corners that need it (in this example, border-radius: 0 4px 0 16px):
body {
display: flex;
justify-content: center;
margin: 0;
height: 100vh;
}
.container {
position: relative;
box-sizing: border-box;
flex: 1 1 100%;
margin: 16px;
padding: 16px;
border: 4px solid black;
border-radius: 12px;
overflow: hidden;
}
.block {
position: relative;
box-sizing: border-box;
width: 100%;
height: 100%;
border: 4px solid black;
border-radius: 8px;
background: linear-gradient(90deg, transparent 50%, rgba(152,47,138,.5) 50%) antiquewhite;
background-size: 20px 20px;
font-weight: bold;
/* This is the only one what won't work: */
/* overflow: hidden; */
}
.filter {
position: absolute;
top: 0;
right: 0;
width: 50%;
height: 50%;
background: #42ADD77D;
backdrop-filter: blur(4px);
/*
Add border-radius only top right corner (which should match the parent's border-radius minus its
border-width) and bottom left corner:
*/
border-radius: 0 4px 0 16px;
}
<div class="container">
<div class="block">
<div class="filter"></div>
</div>
</div>
I'm using Chrome Version 78.0.3904.108 (Official Build) (64-bit) on Windows 10.
Here's my issue:
I have a mockup from a design company that wants a text block with a 'broken' square border behind some big text that looks like this (description: there is a small white frame behind large text that is broken up by the text, and then a smaller text link below):
Image of an element on client's website,
In the design, the text is displayed accross the white square frame. The way I have implemented it right now is to make the big text's background color gray. Because the current image's background is gray the desired effect is achieved.
What is needed is to achieve that effect (of breaking the white frame) REGARDLESS of the appearance of the image. Because right now, this happens:
the gray background of the text appears like a box in front of the image -- it ought to be transparent
To further illustrate, if I set the background-color of the big text to transparent, the whole frame is shown (the desired effect is a broken frame):
background: transparent #1
More info if it helps:
The white frame element is just a div with a white border.
I am not sure exactly what to search for in this case, if there is an appropriate CSS solution (preferrable) or if I need to use SVG or maybe a PNG? Thank you for any help.
As #Temani Afif pointed out in the comments, it's not one box, but two separate shapes in CSS.
I made an example to illustrate this using flexbox.
.page {
background-color: black;
width: 400px;
height: 400px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.box-top {
width: 100px;
height: 10px;
border-color: white;
border-width: 2px;
border-style: solid;
border-bottom: none;
}
.box-bottom {
width: 100px;
height: 30px;
border-color: white;
border-width: 2px;
border-style: solid;
border-top: none;
}
.separator {
color: white;
width: 100%;
margin: 5px 0;
padding: 0;
font-size: 40px;
text-align: center;
}
<div class="page">
<div class="box-top"></div>
<p class="separator">
Headline
</p>
<div class="box-bottom"></div>
</div>
You can make a square element with a border and use a mask on it:
body {
margin: 0;
min-height: 100vh;
background: black;
box-sizing: border-box;
padding-top: 1px;
}
h2.fancy {
position: relative;
text-align: center;
color: white;
padding-top: 12px;
}
h2.fancy:before {
content: '';
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100px;
height: 100px;
border: 5px solid white;
clip-path: polygon(0 0, 100% 0, 100% 10px, 0 10px, 0 40px, 100% 40px, 100% 100%, 0 100%);
}
<h2 class=fancy>I'm a fancy title...</h2>
The advantage of this solution is that you can make it scale easily with what might change on various screen sizes. For example, with the title's font-size:
document.querySelector('input.font-size').addEventListener('input', function(e) {
document.querySelector('h2').style.fontSize = e.target.value + 'px';
})
body {
margin: 0;
min-height: 100vh;
background: url(https://picsum.photos/800) center /cover;
box-sizing: border-box;
padding-top: 1px;
}
.overlay {
position: absolute;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.5);
}
h2.fancy {
z-index: 1;
position: relative;
text-align: center;
color: white;
padding-top: 12px;
}
h2.fancy:before {
content: '';
position: absolute;
left: 50%;
top: 0;
transform: translateX(-50%);
width: 100px;
height: 100px;
display: block;
border: 5px solid white;
clip-path: polygon(0 0, 100% 0, 100% 10px, 0 10px, 0 calc(10px + 1.3em), 100% calc(10px + 1.3em), 100% 100%, 0 100%);
}
input[type=range] {
position: absolute;
bottom: 1rem;
left: 1rem;
z-index: 1;
}
<h2 class=fancy>I'm a fancy title...</h2>
<div class=overlay></div>
<input type=range min=12 max=36 class=font-size>
The disadvantage is that it doesn't work in IE or Edge lower than 18 or in Opera mini. This particular example works in IE 18, though, as it only uses polygon().
i have a div in another div whose height is 48px and position relative. now i have a child div in the div whose height is 48px. i want the child div max-height to be set to 80% and min-height set to 40%. in doing so, the child divs height is just 48px.
Below is the code,
<div class="top_div">
<div class="drawer">
<div class="menu">
<header>
<Svg>
<button></button>
</header>
<ul>
<li></li>
</ul></div></div></div>
.top_div {
z-index: 1;
display: flex;
position: relative;
width: 100%;
height: 48px;
padding: 0 12px 0 12px;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.3);
align-items: center;
}
.drawer {
display: flex;
flex-direction: column;
background-color: $white;
position: absolute;
width: 380px;
top: 55px;
right: 8px;
min-height: 40%;
max-height: 80%;
header {
height: 41px;
border-bottom: 1px solid #CCCCCC;
display: flex;
align-items: center;
justify-content: space-between;
padding-right: 0px;
padding-top: 2px;
svg {
margin-left: 16px;
}
}
ul {
overflow-x: hidden;
}
::after {
content: " ";
position: absolute;
bottom: 100%;
left: 83%;
margin-left: -5px;
border-width: 14px;
border-style: solid;
border-color: transparent transparent $white transparent;
}
}
If i remove position : relative for top_div then it works well but remove the box-shadow for topbar...how can i fix this. I want the box-shadow to be there. or if i keep position:relative for top_div then i want the height of the drawer to be 80%.
How can i fix this. could someone help me. thanks.
I inserted the code into an html document, and set the position of your child's div to relative. For me this solved the issue, and I got exacly what you want to do.
Try this.
I hope this can help, for me it helped.
I have an absolute positioned div inside an overflow: auto, as here:
There 5 row divs with position relative, and I have a .grayBlock inside the row 2 div.
As you can see, the gray block is cut off due to the overflow: auto.
I want it to escape the container. What can I do?
You can construct an additional canvasInfo__block around the current one. It should be a little bit wider as the internal block (in my example, canvasInfo__block2).
The overflow: auto will surely cut, you can't do anything with it, but it won't be very bad because it is enough wide, to contain the internal canvasInfo__block2 and also the gray block overflowing from it.
canvasInfo__block2 needs an overflow: visible, while the external canvasInfo__block can get its overflow: auto.
The result:
HTML:
.canvasInfo
.canvasInfo__title
h3 Title
.hr
.canvasInfo__block
.canvasInfo__block2
.canvasInfo__slider sliderBar
.canvasInfo__activity Motion activity
.row
.circle
span line1
.row
.circle
span line2
.grayBlock hi2
.row
.circle
span line3
.row
.circle
span line4
.row
.circle
span line5
CSS:
.canvasInfo {
margin: 0 auto;
width: 500px;
}
.hr {
margin: 10px 0;
border-bottom: 1px solid red;
}
.canvasInfo__block {
position: relative;
overflow: auto;
width: 400px;
height: 120px;
border: 2px solid red;
}
.canvasInfo__block2 {
position: relative;
overflow: visible;
height: 300px;
width: 300px;
margin-left: auto;
margin-right: auto;
border: 2px solid blue;
}
.grayBlock {
width: 50px;
height: 50px;
background-color: gray;
position: absolute;
top: 0px;
left: -20px;
z-index: -1;
}
.row {
border: 1px solid gray;
position: relative;
}
.circle
{
position: relative;
width: 10px;
height: 10px;
display: inline-block;
border-radius: 60px;
box-shadow: 0px 0px 2px #000;
span {
margin-left: 20px;
}
}
I am trying to make an arrow that looks like this:
However, this is the closest I can get to it:
.button {
margin: 4em 0;
padding: 2em;
width: 15%;
margin: 0 auto;
text-align: center;
background-color: #000000;
color: #ffffff;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-moz-flex-flow: row wrap;
-webkit-flex-flow: row wrap;
-ms-flex-flow: row wrap;
flex-flow: row wrap;
webkit-justify-content: center;
justify-content: center;
}
.curved-arrow {
display: inline-block;
border-top: 10px solid #fff;
border-bottom: 10px solid #fff;
border-left: 30px solid #fff;
border-top-right-radius: 100%;
border-bottom-right-radius: 100%;
}
<div class="button">
<div class="curved-arrow"></div>
</div>
Is this even possible? I know I can use images, but my designer made several of these in multiple colors to use throughout the site that I'd rather just use CSS for the shape.
If it's hard to see it's a flat straight line from top to bottom on the left, and curves in to the middle on the right.
SVG
CSS border radius won't let you get the exact output you are looking for easily. I would suggest an inline SVG with the path element with one quadratic bezier command :
svg{width:100px;}
<svg viewbox="0 0 20 8">
<path d="M0 0 Q 30 4 0 8" />
</svg>
Then you can color the arrow with the CSS fill property, see this fiddle (credits to #Nick R for the example posted in the comments)
CSS
You can also use the 2 values for the border-radius property (see MDN for an explanation of how it works) it is simple but it won't let you make the arrow 'point' as sharp as it is in your image :
.curved-arrow {
width:40px; height:25px;
background:#000;
border-top-right-radius:100% 50%;
border-bottom-right-radius:100% 50%;
}
<div class="curved-arrow"></div>
CSS
This requires just a bit of fancy border-radius styling to achieve the shape you want.
.container {
width: 100px;
height: 100px;
background: red;
position: relative;
}
.arrow {
width: 50px;
height: 30px;
position: absolute;
top: 32px;
left: 25%;
border-radius: 0px 100% 100% 0px / 0 50% 50% 0;
background: white;
}
<div class="container">
<div class="arrow"></div>
</div>
If you want it in a single element, you can just use a psuedo element like so.
.arrow {
width: 100px;
height: 100px;
background: red;
position: relative;
}
.arrow:before {
content: '';
width: 50px;
height: 30px;
position: absolute;
top: 32px;
left: 25%;
border-radius: 0px 100% 100% 0px / 0 50% 50% 0;
background: white;
}
<div class="arrow"></div>
SVG
A good alternative would also be SVG to create this shape which also makes it fully responsive.
<svg width="100px" height="100px" viewbox="0 0 20 20" style="background: red;">
<path d="M5,7
Q15,7 15,10
Q15,13 5,13z" fill="white"></path>
</svg>
I think I've made something quite similar, maybe you could change some margins/widths or heights:
#arrow{
display: block;
box-sizing: content-box;
float: none;
width: 130px;
height: 50px;
top: auto;
right: auto;
bottom: auto;
left: auto;
margin: 0;
padding: 0;
overflow: visible;
outline: none;
border: 0 solid rgba(0,0,0,1);
-webkit-border-radius: 50%;
border-radius: 50%;
background: #1abc9c;
box-shadow: none;
text-shadow: none;
margin-left:-65px;
}
#arrow:after {
position:absolute;
left:-65px;
width:65px;
background:transparent;
content:'';
}
It should be an oval, which i hide by an half by using :after ( quite dirty trick )
js fiddle
However, I would recomend you to use CSS sprites, I guess they should fit best your situation, because CSS shapes are not that easy to read for browsers.
Hope it helps! :)
Here's my take on it. Not quite as sharp a point as I'd like, but it's a little bit closer. Edit: second take uses two pseudo-elements to help sharpen the angle.
.button { margin: 4em 0; padding: 2em; width: 15%; margin: 0 auto; text-align: center; background-color: #000000; color: #ffffff; isplay: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -moz-flex-flow:row wrap; -webkit-flex-flow:row wrap; -ms-flex-flow:row wrap; flex-flow:row wrap; webkit-justify-content: center; justify-content: center; }
.curved-arrow {
position: relative;
display: inline-block;
height: 36px;
width: 56px;
overflow: hidden;
}
.curved-arrow:after {
content: '';
position: absolute;
right: 0;
top: 0;
border-radius: 0 100% 0 0;
height: 50%;
width: 200%;
background: #FFF;
}
.curved-arrow:before {
content: '';
position: absolute;
right: 0;
bottom: 0;
border-radius: 0 0 100% 0;
height: 50%;
width: 200%;
background: #FFF;
}
<div class="button">
<div class="curved-arrow"></div>
</div>
Something like this?
#arrow-base {
width: 120px;
height: 80px;
background: red;
}
#arrow {
width: 0;
height: 0;
border-top: 16px solid transparent;
border-bottom: 16px solid transparent;
border-left: 32px solid white;
display: inline-block;
margin: 24px 44px;
border-radius: 2px;
}
<div id="arrow-base">
<div id="arrow">
<!-- should be empty -->
</div>
</div>