Trapezoid form with percentage units - css

In my Next.js app (basically React) I am trying to draw a trapezoid form with Styled Components, using borders.
My code is like this:
const StyledContainer = styled.div`
position: relative;
border-right: 75px solid red;
border-top: 25px solid transparent;
height: 50%;
width: 75%;
display: flex;
`
However, for my purposes, I need the border-right and border-top properties to use percentages. But when I insert 75% instead of 75px in border-right, the trapezoid is not visible anymore.
I've tried the whole day to fix this but I didn't manage. Anyone have any idea what I need to do? 🙏
For context, the parent container has both width and height properties:
const SAGraph = styled.div`
width: 100%;
height: 100%;
display: flex;
align-items: flex-end;
background-color: hotpink;
`;
I have seen similar problems which were solved by using vw as unit, but this isn't helpful in my case, as I need to use percentages, to make sure that the trapezoid doesn't move outside the container and it uses the whole width of the container...
Edit: This is a picture of my desired output:

If the red section is just for decoration, you can add it to the parent element as a pseudo after element, colored red and clipped into the required shape using CSS clip-path and percentage coordinates.
* {
margin: 0;
}
body {
width: 100vw;
height: 100vh;
}
.SAGraph {
width: 100%;
height: 100%;
display: flex;
align-items: flex-end;
background-color: hotpink;
position: relative;
}
.SAGraph::after {
content: '';
width: 100%;
height: 100%;
position: absolute;
background: red;
bottom: 0;
left: 0;
clip-path: polygon(0 100%, 0 60%, 60% 50%, 60% 100%);
}
<div class="SAGraph"></div>
If you want the red bit to be an actual child element then use the same technique direct on a child element (not on a pseudo element).

Related

Issues with Background Larger than Circle Div CSS

I try to customize dots with React Slick and have this issue with the background color.
Here is how I set the styles.
.slick-dots.circle-dots {
list-style-type: none;
display: flex !important;
justify-content: center;
padding: 0;
.slick-active {
background-color: red;
background-size: contain;
border-radius: 50%;
}
}
An this is the result. The background is actually larger than the circle with border-radius: 50%. As there dots are placed next to each other, it's easy to point out that one is bigger than the others and it's weird. Is there any way that I can fix it?
Since .slick-active is a child of .slick-dots.circle-dots, setting
.slick-dots.circle-dots {
list-style-type: none;
display: flex !important;
justify-content: center;
padding: 0;
overflow: hidden;
//hide anything that spans larger than the element
.slick-active {
background-color: red;
background-size: contain;
border-radius: 50%;
}
}
to hide overflows could work

CSS code to make Gif play outside of hover area

I’m creating a simple webpage for Halloween. I have a background JPG of a starry night sky with a moon in the center. Background 500px by 500px. Moon area would be roughly 100px by 100px center on the image. I have a gif I made of a witch that fly’s across the entire night sky of the background on hover (in front of the moon). Works fine.
I just want the hover area (mouse in/mouse out) to be the moon area itself instead of the whole night sky. The witch gif is triggered if you hover only over the moon but still fly across the whole width of the night sky background. Whenever I contain the hover area to just the moon, the gif is only visible in the moon area instead of the whole night sky.
Can you have a gif area 500px by 500px but the hover area to trigger it is only 100px by 100px center? I’ve searched the site and didn’t quite find what I was looking for. Any help is appreciated. Thanks!
This is the simple working HTML code below:
.backgrounds {
height: 500px;
width: 500px;
background-image: url('Background_moon.jpg');
}
.backgrounds:hover {
cursor: pointer;
background: url('flying_witch.gif'), url('Background_moon.jpg');
}
<div class="backgrounds"></div>
You can create a div for the moon area and another div for the witch inside the .backgrounds element. The witch element must be after the moon area element:
<div class="backgrounds">
<div class="moon-area"></div>
<div class="witch"></div>
</div>
First, let's centralize the .moon-area element.
You can centralize it in 2 different ways.
1) Flexbox: using on the parent display: flex, justify-content: center (horizontally) and aling-items: center (vertically), like this:
.backgrounds {
background-image: url('Background_moon.jpg');
height: 500px;
width: 500px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.moon-area {
width: 100px;
height: 100px;
z-index: 1;
}
2) Auto margin: using position: relative on the parent, and position: absolute on the .moon-area with some positioning (left, right, top, bottom) and margin: auto properties:
.backgrounds {
background-image: url('Background_moon.jpg');
height: 500px;
width: 500px;
position: relative;
}
.moon-area {
width: 100px;
height: 100px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
z-index: 1;
}
We have also the .witch CSS:
.witch {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
}
So, you can apply the hover effect on .moon-area element. We can use the very uself ~ selector to select the next sibling.
.moon-area:hover ~ .witch {
cursor: pointer;
background: url('flying_witch.gif'), url('Background_moon.jpg');
}
Also, don't forget to set z-index: 1 to the .moon-area element and position: relative to the .backgrounds element.

Making a cutout-like div with a z-translated background

I want to make divs which got backgrounds that have this 3d-effect while scrolling, that one can achieve with translateZ. In the end it should look like cutouts or windows and through them you can see the (background-)images.
edit: So, if you scroll through the page you can see those boxes/cutouts but the images inside them are moving slower while scrolling to create the effect that they are further away. end of edit
What I have in mind is to have one div for the cutout and then another div inside it for the background. So, i set it up and it didn't work. It turns out that the overflow: hidden; of the outer div somehow blocks the transform: translateZ(-5px) scale(1.05); of its child.
Here is what I have got so far:
body {
perspective: 100px;
transform-style: preserve-3d;
overflow-x: hidden;
overflow-y: scroll;
}
#artwork, #photos {
width: 800px;
padding: 0 50px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
}
.pic {
/*position: relative;*/
width: 200px;
height: 100px;
display: inline-block;
background: #aaa;
border-radius: 10px;
box-shadow: inset 0 10px 30px rgba(0,0,0,.3);
}
#artwork > * {
overflow: hidden;
}
.pic div {
position: absolute;
width: 200px;
height: 110px;
background: #660; /*couldn't put an image here*/
background-size: cover;
transform: translateZ(-5px) scale(1.05);
}
<section id="artwork">
<div class="pic"><div></div></div>
<div class="pic"><div></div></div>
<div class="pic"><div></div></div>
</section>
P.S.: I don't want to achieve the effect via JavaScript because it's not working smoothly on most computers.
edit n°2: my approaches so far:
- making extra tick borders to cover overlapping parts of the image divs; instead of using overflow: hidden >> parts are sometimes still overlapping on some screen sizes & it takes a lot of space
- creating a clip-path to use as overflow: hidden >> clip-paths also break the translateZ
- playing around with display and position on both outer and inner div >> only solutions without cutout
- Ztranslating the parent of the outer div further away and then bringing the outer div close again >> still blocked by the overflow: hidden;
I found a workaround, although it's a compromise because the border radius isn't working. I added thick borders in the background color to the outer divs and set the z-index of the inner divs to something negative.
body {
height: 200px;
perspective: 100px;
transform-style: preserve-3d;
overflow-x: hidden;
overflow-y: scroll;
}
#artwork {
width: 800px
padding: 0 50px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
}
.pic {
width: 200px;
height: 100px;
margin: -40px;
display: inline-block;
background: transparent;
border: 40px solid hsl(30, 50%, 90%);
box-shadow: inset 0 10px 30px rgba(0,0,0,.3);
}
.pic div {
position: absolute;
width: 200px;
height: 110px;
background: linear-gradient(135deg, rgba(240,183,161,1) 0%,rgba(140,51,16,1) 50%,rgba(117,34,1,1) 51%,rgba(191,110,78,1) 100%);
transform: translateZ(-5px) scale(1.05) translateY(-1vw);
z-index: -20;
}
#artwork div:nth-child(2) div, #photos div:nth-child(2) div {transform: translateZ(-5px) scale(1.05) translateX(-1.5vw) translateY(-1vw);}
#artwork div:nth-child(4) div, #photos div:nth-child(4) div {transform: translateZ(-5px) scale(1.05) translateX(1.5vw) translateY(-1vw);}
<br><br><br><br><br><br><br>
<section id="artwork">
<div class="pic"><div></div></div>
<div class="pic"><div></div></div>
<div class="pic"><div></div></div>
</section>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
that code snippet doesn't work here for some reason. For me however it works in the browser. It would be nice if someone could suggest another possible solution as this one works with only some screen sizes.

"Stick" an svg to the top of an element as it's resizing

I'm trying to add a stylish "wave" element to the top of a div, however with my attempts, the svg moves from its position and leaves a gap when the browser resizes.
Here's a mockup of what it should look like:
CSS:
.wave {
position: absolute;
top: -72px;
}
.container {
background: #eee;
}
.col-1 {
height: 200px;
}
.col-2 {
position: relative;
background: #fff;
height: 100px;
width: 100%;
margin-top: 100px;
}
My other attempt was using background-image: url(wave.svg); in a :after selector, but same results.
Here's a codepen:
https://codepen.io/anon/pen/LmRyLK
How can I get the wave to keep put as is when it's resizing and when it's not?
Set your SVG as a background image on the element where you have your funky purple bit, you can stack the background images on each other, like so:
.purpleElement{
background: url("/path/to/asset/image.svg") bottom center no-repeat, purple;
background-size: 100%;
/*I've set a height here to replicate content*/
height: 70vh;
width: 100%;
}
I've forked off your codepen to show what will happen

Layer div with css shape cut-out over a div with bg color

I'm trying to indicate the active link, using a triangle-shaped CSS "cut-out" (the triangle is cut out of the white header.
http://codepen.io/Goatsy/pen/xVvRmZ
/*
.container {
width: 1200px;
}
*/
How do I "cut out" the red triangle from both the contained header and full-width background (red) block? I need to cut out the triangle to expose underlying photo.
The header works great, but as soon as the full-width red block is applied to the background layer of contained header, it "fills in" the triangle cut-out.
UPDATE:
I created a flexbox within a flexbox. Unfortunately, the contained header is not exactly 1200px, and this will be difficult to apply to the overall layout.
http://codepen.io/Goatsy/pen/xVvRmZ
.wrapper-whole {
display: flex;
flex-direction: row;
height: 134px;
margin: auto;
}
.flexy {
background: #f00;
flex: 2;
height: 134px;
}
.wrapper { /* wraps contained header navbar */
display: flex;
flex-direction: row;
height: 134px;
border-left: 15px solid #fff;
border-right: 15px solid #fff;
max-width: 1200px;
margin: auto;
flex: 6;
}
Instead of cutting it out from a background, you could create the illusion of a background by making red elements on each side of the white header using :before and :after pseudo-elements.
In http://codepen.io/anon/pen/MyNpdX, I added the following CSS:
.wrapper {
/* the stuff that was already here */
position: relative;
}
.wrapper:after, .wrapper:before{
content: "";
background-color: #f00;
width: 4000px;
position: absolute;
height: 134px;
top: 0;
}
.wrapper:before{
margin-right: 15px;
right: 100%;
}
.wrapper:after{
left: 100%;
margin-left: 15px;
}
Too many questions:
let me try to answer the ones I've understood.
I'll keep editing this answer as I go:
to contain something: you can have the following parent div
.parent {
max-width: 1200px;
overflow: hidden;
}
this way a child red div, would not appear outside parents constraint.
you can achieve css-triangles as:
.arrow-up {
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-bottom: 15px solid black;
}
<div class="arrow-up"></div>
p.s.: you're codepen is so far behind the layout in question, that it's hard to hands-on fix the problem
Place the contained flexbox header, inside of another flexbox.
Place one (red) block on left of header and one (red) block on right.
Create max-width for white header:
#media screen and (min-width: 480px) {
.wrapper { /* wraps contained header navbar */
min-width: 1200px;
}
}
http://codepen.io/Goatsy/pen/xVvdKN

Resources