There are a few answers out there about how to skew the single side of a div both empty and with images:
CSS3 Transform Skew One Side
Skew one side only of an element
But using these answers, I cannot figure out the rest of my issue.
I am attempting to create a 2 column row with an image background for the second column and a skewed or angled left side. The problem I have is filling the space with the containers after they have been skewed.
I am using Foundation 6 as the primary framework behind my site.
I have attached an image of how it should look completed
The closest I have got so far is this:
I have posted the code I have so far below.
Codepen
HTML:
<section class="lan_primary">
<div class="container-full">
<div class="row wide">
<div class="columns small-12 medium-6 lan_primary--select">
CONTENT LEFT
</div>
<div class="columns small-12 medium-6 lan_primary--img">
CONTENT
</div>
</div>
</div>
</section>
CSS:
div {
border: 1px red solid;
}
.lan_primary {
width: 100%;
height: 80vh;
margin-top: 10vh;
overflow: hidden;
.row {
flex-flow: row !important;
overflow: hidden;
}
&--select,
&--img {
padding: 100px 0;
overflow: hidden;
position: relative;
}
&--select {
background-color: aqua;
}
&--img {
background-color: blue;
transform-origin: top left;
transform: skew(-20deg);
//margin-left: 80px;
}
}
UPDATE - from first answer
Adding a pseudo element to solve causes problems with variable heights. If I were to set 100vh, it would give a different result to if I were to set height: 700x;.
See image below:
Use the triangle border trick with a pseudo. With viewport units it will scale with the height
To make the skew centered, I sized the right 25px (half of the skewed
area) wider than the left.
html, body {
margin: 0;
}
.wrapper {
display: flex;
}
.left, .right {
height: 100vh;
}
.left {
flex-basis: calc(50% - 25px);
position: relative;
background: lightgray;
display: flex;
align-items: center;
}
.left::after {
content: '';
position: absolute;
top: 0;
left: 100%;
height: 0;
width: 0;
border-top: 100vh solid lightgray;
border-right: 50px solid transparent;
}
.right {
flex-basis: calc(50% + 25px);
background: url(http://lorempixel.com/500/500/people/10/) left center no-repeat;
background-size: cover;
}
<div class="wrapper">
<div class="left">
<h1>Some text</h1>
</div>
<div class="right"></div>
</div>
You can Make use of the pseudo elements to make the look skewed one side
CSS(SCSS)
div {
border: 1px red solid;
}
.lan_primary {
width: 100%;
height: 80vh;
margin-top: 10vh;
overflow: hidden;
.row {
flex-flow: row !important;
overflow: hidden;
}
&--select,
&--img {
padding: 100px 0;
overflow: hidden;
position: relative;
}
&--select {
background-color: aqua;
position: relative;
overflow:visible;
&::after{
content:"";
position: absolute;
z-index:1;
top:0;
bottom:0;
height:100%;
width:20%;
background-color: cyan;
right:-40px;
transform:skew(-20deg);
}
}
&--img {
background-color: blue;
transform-origin: top left;
//margin-left: 80px;
}
}
link for reference
hope this helps
Related
I'm building a fullscreen modal, and I'm trying to center the content vertically when it is smaller than the screen, and to start at the top and allow scroll, when the hight is larger than the hight of the container. I'm trying to use position:fixed to position the container on the screen, and display:flex; align-items:center; to center the inner div. When the container is shorter than the inner div the top part of the inner div is cut out, even when I use: overflow-y:scroll.
Here is my code:
<div class="modal">
<div class="inner-w">
hello world
<div class="long-box">
</div>
</div>
</div>
.modal {
position: fixed;
bottom: 70px;
top: 0;
left:0;
right: 0;
display: flex;
align-items: center;
padding: 15px;
overflow: scroll;
}
.inner-w {
margin: 50px 0;
width: 100%;
}
.long-box {
height: 400px;
width: 100%;
border: 1px solid brown;
}
here is a jsfiddle: https://jsfiddle.net/benCarp/bh2Lfpo4/18/#&togetherjs=aKbe8NLJSR
add to .modal{flex-direction-column;} now you can remove the margin
.modal {
position: fixed;
bottom: 70px;
top: 0;
left:0;
right: 0;
display: flex;
flex-direction:column;
align-items: center;
padding: 15px;
overflow: scroll;
}
.inner-w {
width: 100%;
}
.long-box {
height: 400px;
width: 100%;
border: 1px solid brown;
}
<div class="modal">
<div class="inner-w">
hello world
<div class="long-box">
</div>
</div>
</div>
#godfather had an excellent suggestion to change the direction of the flex container from row to column with .modal{flex-direction-column;}. It better describes our layout, and the width and margin property aren't needed any more. However it is not enough. overflow: scroll (or "auto") property isn't inherited, and should be placed on the actual element that overflows - the .inner-w class.
Here is how the css should look:
.modal {
position: fixed;
flex-direction:column;
bottom: 70px; // kept for a button
top: 0;
left:0;
right: 0;
display: flex;
padding: 15px;
justify-content: center;
}
.inner-w {
overflow: auto;
}
.long-box {
height: 400px;
width: 100%;
border: 1px solid brown;
}
I'm trying to make a centered div with another div on the right of it. So the div on the left is horizontal centered. De div on the right is directly on the right of the centered div. I've tried it in many ways with different displays and margins etc but I can't seem to figure it out.
All tips are welcome!
div {
width: 100px;
height: 100px;
display: inline-block;
}
#left {
left: 50%;
background: #009a9a;
}
#right {
background: #bbad4f;
}
<div id="left"></div>
<div id="right"></div>
You can do it with the Flexbox and positioning:
.flex-container {
display: flex; /* displays flex-items (children) inline */
justify-content: center; /* centers them horizontally */
position: relative;
}
.flex-container > div {
width: 100px;
height: 100px;
}
#left {
background: #009a9a;
}
#right {
position: absolute;
left: 50%; /* moved right by half of the parent's width */
transform: translateX(50%); /* and half of its own width */
background: #bbad4f;
}
<div class="flex-container">
<div id="left"></div>
<div id="right"></div>
</div>
No matter the divs width (as long as they stay the same), this solution is dynamic, therefore no unnecessary margins or calc().
But with the help of CSS variables you can make it completely dynamic:
:root {
--leftWidth: 200px;
}
.flex-container {
display: flex;
justify-content: center;
position: relative;
}
.flex-container > div {
width: 100px;
height: 100px;
}
#left {
width: var(--leftWidth);
background: #009a9a;
}
#right {
position: absolute;
left: calc(50% + (var(--leftWidth)/2)); /* moved right by half of the parent's and sibling's width */
background: #bbad4f;
}
<div class="flex-container">
<div id="left"></div>
<div id="right"></div>
</div>
body,
html {
height: 100%;
font-size: 0;
}
div {
width: 100px;
height: 100px;
display: inline-block;
}
#left {
left: 50%;
top: 50%;
position: relative;
transform: translate(-50%, -50%);
background: #009a9a;
}
#right {
background: #bbad4f;
left: calc(50% + 100px);
top: calc(50% + 100px);
position: relative;
transform: translate(calc(-50% - 100px), calc(-50% - 100px));
}
<div id="left"></div>
<div id="right"></div>
Here another example if you can't use transform or if you don't know elements size. You can do it with flexbox or just just by using margin: auto to center the first element.
.Container {
display: flex;
justify-content: center;
}
.Left {
background-color: red;
position: absolute;
left: 100%;
top: 0;
}
.Centered {
background-color: cyan;
position: relative;
}
/* Demo only */
.Centered, .Left {
border-radius: 4px;
padding: 8px 24px;
}
<div class="Container">
<div class="Centered">
<div class="Left">Right</div>
Centered
</div>
</div>
This is using absolute positions. Please not that the amount of left:150px; is the half width of centered div + half width of left div. Also the style margin-left:200px; on the lef div, comes from the width of centered div.
.container {
position: relative;
}
.centered {
width: 200px;
background: #eeeeee;
position: absolute;
height: 100px;
margin: auto;
left: 0;
right: 0;
}
.leftOf {
background: #ff8800;
position: absolute;
left: 150px;
margin-left: 200px;
height: 100px;
width: 100px
}
<div class="container">
<div class="centered"></div>
<div class="leftOf"></div>
</div>
I'm trying to go with the css-only approach to this issue and not to use margin-left to move the <div class="fd"></div> from <div class="sb"></div>
I've ran out of the idea-fuel what to try. I've nested some wrappers and used different kinds of positionings (this is not a typo nor French, spell-checker excuse me) but nothing has worked out so far.
Issue: Making a fixed div as solid element, to accept the .fd element on it's right side.
.fd holds content which is going to exceed the height of the page.
.sb holds side-content which is going to remain as 100% in height.
See snippet for a clear example what I've been struggling with.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.sb {
height: 100%;
width: 300px;
background: blue;
position: fixed;
opacity: 0.5;
}
.fd {
min-height: 100%;
background-color: red;
display: inline; /* Won't apply to fixed? block will overlap everything */
}
<div class="sb"></div>
<div class="fd">
<p>Am I out in the open?</p>
</div>
Added an extra .wrap.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrap{
padding-left: 300px;
}
.sb {
height: 100%;
width: 300px;
background: blue;
margin-left: -300px;
position: fixed;
opacity: 0.5;
}
.fd {
min-height: 100%;
background-color: red;
display: inline; /* Won't apply to fixed? block will overlap everything */
}
<div class="wrap" id="wrap">
<div class="sb"></div>
<div class="fd">
<p>Am I out in the open?</p>
</div>
</div>
https://jsfiddle.net/afelixj/tb3pbam9/
I'm trying to create the following layout but I cant figure it out.
Div A has a 66% width and fills the remaining space on the left
Div B and C have 33% width and fill the remaning space on the right
All divs are inside a 100% centered container
The import thing is that I want div B and C to have their own background colors. Div A will just use the body's background color.
As I said in this answer
The most obvious solution is just to close the container...have your full width div then open a new container. The title 'container' is just a class...not an absolute requirement that it hold everything all at the same time.
For decoration (background) purposes only,you can use pseudo-elements.
html {
box-sizing: border-box;
}
*,
::before,
::after {
box-sizing: inherit;
}
html,
body {
height: 100%;
}
body {
overflow: hidden;
}
.container {
height: 100%;
width: 50%;
margin: auto;
border-left: 1px solid grey;
border-right: 1px solid grey;
padding-top: 50px;
/* demo purposes only */
}
.box:after {
/* clearfix */
content: "";
display: table;
clear: both;
}
.left {
width: 66.666%;
height: 100px;
float: left;
position: relative;
}
.right {
width: 33.333%;
height: 50px;
float: right;
position: relative;
}
.left::before,
.right::before {
content: '';
position: absolute;
top: 0;
height: 100%;
width: 100vw;
z-index: -1;
}
.left:before { /* left version if required*/
background: lightblue;
right: 0;
}
.one:before {
background: lightgreen;
left: 0;
}
.two:before {
background: pink;
left: 0;
}
<div class="container">
<div class="box">
<div class="left"></div>
<div class="right one"></div>
<div class="right two"></div>
</div>
</div>
This is a follow-up to his question: Center triangle at bottom of div full width responsively
Again I'm stuck with my CSS for a project involving divs with triangle borders at the bottom:
I want a row of cascading divs to look like this (lower tringle colored red for demonstration purposes):
My code now looks like this:
html, body {
padding: 0; margin: 0;
color: white;
}
.top {
background-color: #282C34;
height: 500px;
width: 100%;
position: relative;
}
.bottom {
background-color: #3B3E48;
height: 500px;
width: 100%;
}
.triangle {
border-left: 50vw solid transparent;
border-right: 50vw solid transparent;
width: 0;
height: 0;
bottom: -40px;
content: "";
display: block;
position: absolute;
overflow: hidden;
left:0;right:0;
margin:auto;
}
.upperTriangle {
border-top: 40px solid #282C34;
}
.lowerTriangle {
border-top: 40px solid red;
}
<div class="top">
<div class="triangle upperTriangle"></div>
</div>
<div class="bottom">
<div class="triangle lowerTriangle"></div>
</div>
<div class="top">
<div class="triangle"></div>
</div>
Code on JSFiddle: http://jsfiddle.net/rndwz681/
My problems:
I can't figure out how to align the triangles correctly on the z axis.
I can't figure out how to align the triangles correctly with the divs apart from the first one.
Thanks a lot in advance for the help.
Powered by CSS triangle generator
.container {
width: 100%;
overflow: hidden;
}
.block {
width: 100%;
height: 200px;
}
.block--arrow {
position: relative;
}
.block--arrow:before {
display: block;
content: '';
position: absolute;
top: 0;
left: 50%;
margin-left: -350px;
width: 0;
height: 0;
border-style: solid;
border-width: 100px 350px 0 350px;
}
.grey {
background: #626262;
}
.light-grey {
background: #999999;
}
.light-grey:before {
border-color: #626262 transparent transparent transparent;
}
.black {
background: #000000;
}
.black:before {
border-color: #999999 transparent transparent transparent;
}
<div class="container">
<div class="grey block"></div>
<div class="light-grey block block--arrow"></div>
<div class="black block block--arrow"></div>
</div>
By adding position:relative; to your .bottom class and adding z-index:100; to your .triangle class I was able to get your triangles to appear the way you want them to.
See my fiddle: http://jsfiddle.net/rndwz681/1/
z-index sets the "layer" that an object appears on (higher number = closer to the user). It can only be applied to 'positioned' elements, but your absolute-positioned triangles qualify.