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().
Related
I want it to turn out like this, but unfortunately my triangle goes into the background of the next stage. I spent 3 hours on it. Help please
https://stackblitz.com/edit/angular-3llbmq?file=src/components/sales-funnel/sales-funnel.component.html
Here it is done with polygon, adapt colors yourself
div.container {
display: inline-flex;
align-items: center;
position: relative;
background: black;
width: 100%;
}
div.tangle {
height: 50px;
width: 200px;
clip-path: polygon(0% 20%,
60% 20%,
95% 20%,
100% 50%,
95% 80%,
60% 80%,
0% 80%);
}
div.tangle:nth-child(1) {
background:lightgreen;
transform: translateX(20px);
z-index:3;
}
div.tangle:nth-child(2) {
background:green;
transform: translateX(10px);
}
div.normal {
height: 30px;
width: 200px;
background: white;
}
<div class="container">
<div class="tangle"></div>
<div class="tangle"></div>
<div class="normal"></div>
</div>
This can easily be achieved with the use of ::before and ::after pseudo-elements - with one providing the background of the 'next step' and one providing the triangle with the 'current step' bg color.
Not sure if you neeed a elements in the lis - so I just did straight li's but it would not be hard to change the styling for the use of a elements.
Its best not to try to to use opacity for the step differences - its more accessible to use hex codes directly rather than the one hex code with different opacity values.
Note that the solution of preventing the bleeding color is to space the li's apart with margin and to use the before / after pseudo-elements to fill the gaps - its better to do this than overlap the element over he next step to prevent issues with clicking on areas that are covered by the triangles
ul {
display: flex;
list-style: none;
padding: 0;
border: solid 1px #d4d4d4;
background: lemonChiffon
}
li {
font-size: 16px;
line-height: 20px;
margin-right: 16px;
padding: 4px 32px 4px 8px;
position: relative;
}
.visited {
background: #AFD954;
color: #fff;
}
.visited::before {
content: '';
width: 16px;
height: 28px;
z-index: 5;
position: absolute;
top: 0;
right:-16px;
background: #9BCE29
}
.visited::after {
content: '';
width: 0;
height: 0;
border-top: 14px solid transparent;
border-bottom: 14px solid transparent;
border-left: 14px solid #AFD954;
position: absolute;
right:-14px;
z-index: 9;
top: 0
}
.active {
background: #9BCE29;
color: #fff
}
.active::before {
content: '';
width: 16px;
height: 28px;
z-index: 5;
position: absolute;
top: 0;
right:-16px;
background: lemonChiffon
}
.active::after {
content: '';
width: 0;
height: 0;
border-top: 14px solid transparent;
border-bottom: 14px solid transparent;
border-left: 14px solid #9BCE29 ;
position: absolute;
right:-14px;
z-index: 9;
top: 0
}
.not-visited {
background: lemonChiffon
}
<ul>
<li class="visited">New Deal</li>
<li class="active">Contact</li>
<li class="not-visited">Qualified</li>
</ul>
I had edited your stackbliz example. Please note the HTML and CSS changes.
Don't use opacity to lighten the color. Instead, use SCSS lighten and darken methods.
Please utilize the most of the CSS than the HTML part for the assigning styles. Utilize the classes you have.
NOTE: Please take the benefit of SCSS variables, nesting and pre-defined methods.
Added the reverse z-index to stack the previous element to place over next element.
Below 6 is the total elements
[ngStyle]="{
zIndex: 6 - i
}"
https://stackblitz.com/edit/angular-jhk6qf?file=src/components/sales-funnel/sales-funnel.component.scss
I want to add an underline under my h1 heading and make it just a little short then the heading itself. 30px space should remove from both ends. how to fix this?
<h1>Heading</h1>
h1 {
border-bottom: 2px solid #000000;
width: fit-content;
}
h1 {
position: relative;
display: inline-block;
}
h1:after {
content: "";
width: calc(100% - 60px);
height: 100%;
position: absolute;
left: 30px;
border-bottom: 2px solid black;
}
<h1>Heading</h1>
One way to do it is with ::after element. Use left to shift it for 30px.
It depends a bit on what you want to do if the heading is long and overflows to another (shorter) line, but assuming you literally want just a border shortened by 60px then you can add a before pseudo element of the same height but less width.
h1 {
width: fit-content;
position: relative;
--indent: 30px;
}
h1::before {
width: calc(100% - (2 * var(--indent)));
height: 100%;
content: '';
position: absolute;
top: 0;
left: var(--indent);
;
border-bottom: 2px solid #000000;
}
<h1>Heading</h1>
This snippet defines a variable with the indent required (30px) so it will be easy for you to change it if required.
You may fake the underline via a background and shorten it via background-size:
here is an example of the idea:
h1 {
background: linear-gradient(to top, #000000 0 2px, transparent 2px) 50% 0 / calc(100% - 60px) 100% no-repeat;
width: fit-content;
}
h2 {
color: green;
margin: auto;
background: linear-gradient(to top, currentColor 0 2px, transparent 2px) 50% 0 / calc(100% - 60px) 100% no-repeat;
width: fit-content;
}
h2+h2 {
color: tomato;
line-height: 0.95em;
transition:0.25s
}
h2 + h2:hover {line-height:1.6em;}
<h1>Heading</h1>
<p>extras for infos</p>
<h2>Match colors via currentColor</h2>
<h2>move that fake underline closer or further away</h2>
I have a div which looks something like this:
.box{
box-sizing: border-box;
border: solid 0.01rem #2e2e2e;
border-radius: 3px;
width:100px;
height:100px;
background:red;
}
<div class="box"/>
And I'm trying to achieve this effect. How can I make this box look with such shadows from the inside of the div?
linear gradient
blur filter
absolute positioning
pseudo-elements
flexbox
.box {
box-sizing: border-box;
border-radius: 10%;
width: 100px;
height: 100px;
background: linear-gradient(270deg, red, #c10606);
position: relative;
}
.box:before {
position: absolute;
content: '';
top: 10%;
right: 10%;
bottom: 10%;
left: 10%;
background: linear-gradient(90deg, red, #c10606);
border-radius: 12%;
filter: blur(1px); /* optional for a softer effect */
}
/* optional layout and styling for box contents */
.box {
display: flex;
align-items: center;
text-align: center;
font-family: arial;
color: #ddd;
font-weight: bold;
}
.box * {
position: relative; /* puts interior content over the pseudo-element */
}
<div class="box">
<span>Interior content</span>
</div>
CSS box-shadow
I think the answer posted by #isherwood works as the best one for your use-case. But, there is a way to make the shadow show on the inside of the element by setting the last parameter of box-shadow as inset.
There are a few catches for this solution though. A few things which I could not achieve:
I am unable to implement linear gradient to the shadow.
I am unable to give a border-radius to the inner boundary of the shadow.
div.box {
background: linear-gradient(90deg, hsl(26, 68%, 26%), hsl(26, 68%, 45%));
height: 100px;
width: 100px;
box-shadow: 0 0 0 12px hsl(26, 68%, 35%) inset;
border-radius: 10px;
}
<div class="box"></div>
Reference: How to create an inner shadow using CSS
Well, I edited your code. Here is the demo.
Basically, I added one more div and added some style. Hope it will give you an idea.
Also, I added a snippet down below:-
.box {
box-sizing: border-box;
border: solid 0.01rem #2e2e2e;
border-radius: 15px;
width: 100px;
height: 100px;
background: red;
padding: 10px 0px 10px 0px;
}
.inner-div {
box-sizing: border-box;
border-radius: 15px;
width: 78px;
height: 78px;
background: #ee1717;
margin: 0 auto;
}
<div class="box"/>
<div class="inner-div"></div>
<div>
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;
}
box shadows are basically your shape blurred.
that means that at the edges the shadow is curved up.
what if you don't want that? what if your shadow is for a top bar and you don't want it to seems like it ends?
issue:
desired effect :
how do I obtain this?
html :
<div class="TopBar"> </div>
css :
.TopBar {
box-shadow: 0 4px 28px black;
}
Am I supposed to use an absolute positioned element that's bigger than screen width or something?
You can add a spread parameter to the shadow (not exactly the same appearance, but at least it does what you ask for):
html,
body {
margin: 0;
}
.TopBar {
height: 40px;
background: #444;
box-shadow: 0px 4px 24px 16px black;
}
<div class="TopBar"></div>
Fake it! You can use linear gradient and a pseudo element to get the effect you want:
.TopBar {
height: 50px;
background: gray;
position: relative;
}
.TopBar::after {
content: "";
background: linear-gradient(to bottom, rgba(0,0,0,.8) 0%,rgba(0,0,0,0) 100%);
position: absolute;
width: 100%;
height: 20px;
top: 100%;
}
<div class="TopBar"> </div>
You can add a pseudo-element (:before) to extend it beyond your original container and therefore, get a wider shadow :
html, body { margin:0; padding: 0 }
.TopBar {
height: 50px;
position: relative;
}
.TopBar:before {
content: "";
display: block;
position: absolute;
height: 100%;
width: 100%;
background: #454545;
box-shadow: 0 4px 28px #000;
transform: scaleX(1.1);
z-index: -1;
}
.TopBar .content {
color: #add8e6;
}
<div class="TopBar">
<div class="content">Here's some text inside my top bar</div>
</div>