I am trying to build a react dashboard using Core UI's react template found here.
CSS
.top-stick {
position: sticky !important;
position: -webkit-sticky;
top: 5rem;
overflow-y: auto;
height: calc(100vh - 5rem);
}
JSX
<div className="animated fadeIn">
<Row className="app-scrollable-body">
<Col xs="12" sm="4" md="3" className="top-stick">
<Card className="toic">
<CardBody>
Lorem ipsum dolor sit amet
</CardBody>
</Card>
</Col>
<Col xs="12" sm="8" md="9">
<Card>
<CardHeader>Card title</CardHeader>
<CardBody>
Lorem ipsum dolor sit amet
</CardBody>
</Card>
</Col>
</Row>
<div className="app-fixed-footer">
<span>
CoreUI © 2018
creativeLabs.
</span>
<span className="ml-auto">
Powered by{" "}
CoreUI for React
</span>
</div>
</div>
But on scroll the card does not seem to stick.
On inspecting the CSS is present. Also no overflow: hidden is there in the CSS Tree.
The issue is the use of overflow inside .app-body. It's a bit tricky but there should be no overflow property set to any element between the element that has the scroll and the sticky element.
Here is a basic example to illustrate. The scroll is on the viewport and we have a wrapper with overflow:hidden (or even auto) thus the sticky behavior won't work.
.container {
display:flex;
align-items:flex-start;
border:2px solid green;
}
.content {
flex:1;
height:200vh;
background:red;
margin:10px;
}
.sticky {
flex:1;
height:100px;
background:blue;
margin:10px;
position:sticky;
top:0;
}
.wrapper {
overflow:hidden;
border:2px solid red;
}
<div class="wrapper">
<div class="container">
<div class="sticky"></div>
<div class="content"></div>
</div>
</div>
If we remove the overflow, it will work as expected:
.container {
display:flex;
align-items:flex-start;
border:2px solid green;
}
.content {
flex:1;
height:200vh;
background:red;
margin:10px;
}
.sticky {
flex:1;
height:100px;
background:blue;
margin:10px;
position:sticky;
top:0;
}
.wrapper {
border:2px solid red;
}
<div class="wrapper">
<div class="container">
<div class="sticky"></div>
<div class="content"></div>
</div>
</div>
If we keep the overflow within the wrapper but we move the scroll to the container element it will also work because there is no element with overflow set between the scroll and the sticky element:
.container {
display:flex;
align-items:flex-start;
border:2px solid green;
max-height:200px;
overflow:auto;
}
.content {
flex:1;
height:200vh;
background:red;
margin:10px;
}
.sticky {
flex:1;
height:100px;
background:blue;
margin:10px;
position:sticky;
top:0;
}
.wrapper {
overflow:hidden;
border:2px solid red;
}
<div class="wrapper">
<div class="container">
<div class="sticky"></div>
<div class="content"></div>
</div>
</div>
Related: What are `scrolling boxes`?
Related
I am trying to build a react dashboard using Core UI's react template found here.
CSS
.top-stick {
position: sticky !important;
position: -webkit-sticky;
top: 5rem;
overflow-y: auto;
height: calc(100vh - 5rem);
}
JSX
<div className="animated fadeIn">
<Row className="app-scrollable-body">
<Col xs="12" sm="4" md="3" className="top-stick">
<Card className="toic">
<CardBody>
Lorem ipsum dolor sit amet
</CardBody>
</Card>
</Col>
<Col xs="12" sm="8" md="9">
<Card>
<CardHeader>Card title</CardHeader>
<CardBody>
Lorem ipsum dolor sit amet
</CardBody>
</Card>
</Col>
</Row>
<div className="app-fixed-footer">
<span>
CoreUI © 2018
creativeLabs.
</span>
<span className="ml-auto">
Powered by{" "}
CoreUI for React
</span>
</div>
</div>
But on scroll the card does not seem to stick.
On inspecting the CSS is present. Also no overflow: hidden is there in the CSS Tree.
The issue is the use of overflow inside .app-body. It's a bit tricky but there should be no overflow property set to any element between the element that has the scroll and the sticky element.
Here is a basic example to illustrate. The scroll is on the viewport and we have a wrapper with overflow:hidden (or even auto) thus the sticky behavior won't work.
.container {
display:flex;
align-items:flex-start;
border:2px solid green;
}
.content {
flex:1;
height:200vh;
background:red;
margin:10px;
}
.sticky {
flex:1;
height:100px;
background:blue;
margin:10px;
position:sticky;
top:0;
}
.wrapper {
overflow:hidden;
border:2px solid red;
}
<div class="wrapper">
<div class="container">
<div class="sticky"></div>
<div class="content"></div>
</div>
</div>
If we remove the overflow, it will work as expected:
.container {
display:flex;
align-items:flex-start;
border:2px solid green;
}
.content {
flex:1;
height:200vh;
background:red;
margin:10px;
}
.sticky {
flex:1;
height:100px;
background:blue;
margin:10px;
position:sticky;
top:0;
}
.wrapper {
border:2px solid red;
}
<div class="wrapper">
<div class="container">
<div class="sticky"></div>
<div class="content"></div>
</div>
</div>
If we keep the overflow within the wrapper but we move the scroll to the container element it will also work because there is no element with overflow set between the scroll and the sticky element:
.container {
display:flex;
align-items:flex-start;
border:2px solid green;
max-height:200px;
overflow:auto;
}
.content {
flex:1;
height:200vh;
background:red;
margin:10px;
}
.sticky {
flex:1;
height:100px;
background:blue;
margin:10px;
position:sticky;
top:0;
}
.wrapper {
overflow:hidden;
border:2px solid red;
}
<div class="wrapper">
<div class="container">
<div class="sticky"></div>
<div class="content"></div>
</div>
</div>
Related: What are `scrolling boxes`?
I have an image which is on the right and the text needs to be beside it on the left with the start of the text inline with the top of the image, how would I do this?
#pic0 {
width:100%;
}
#pic0img {
display: inline-block;
height: auto;
margin-left:50%;
width:100%;
margin-bottom:5px;
}
pic0txt {
margin-right:52%;
width:48%;
}
<div id="pic0">
<div id="pic0img">
<img src="Images/Activities/pic0.fw.png" width="50%"
onmouseover="this.src='Images/Activities/pic0.fw.png'"
onmouseout="this.src='Images/Activities/pic0.fw.png'" />
</div>
<div id="pic0txt">
<p>test</p>
</div>
</div>
See this simplified snippet (remove borders which are just for test):
#pic0txt {
display: inline-block; border:1px solid red;
text-align:center;
vertical-align:top;
width:48%;
}
#pic0img {
display: inline-block; border:1px solid red;
width:48%;
}
<div>
<div id="pic0txt">test</div>
<img id="pic0img" src="https://www-asp.azureedge.net/v-2016-11-01-012/images/ui/home-free-courses.png" />
</div>
<hr/>
<div>
<img id="pic0img" src="https://www-asp.azureedge.net/v-2016-11-01-012/images/ui/home-free-courses.png" />
<div id="pic0txt">test</div>
</div>
Use flex on the parent, then flex-grow on each flex item so they'll be 50% width, and set the image to width: 100% so it fills it's parent.
.flex {
display: flex;
}
.flex > div {
flex-grow: 1;
flex-basis: 0;
}
img {
width: 100%;
}
<div class="flex">
<div>
<p>text</p>
</div>
<div>
<img src="http://www.w3schools.com/css/paris.jpg">
</div>
</div>
Try this simple and easy trick:
<div id="pic0">
<div id="pic0img">
<p> <img src="http://images5.fanpop.com/image/photos/31300000/beautiful-heart-pic-beautiful-pictures-31395948-333-500.jpg" width="50%"
onmouseover="this.src='Images/Activities/pic0.fw.png'"
onmouseout="this.src='Images/Activities/pic0.fw.png'" />test</p>
</div>
</div>
#pic0 {
width:20%;
}
#pic0img {
display: inline-block;
height: auto;
margin-left:50%;
width:100%;
margin-bottom:5px;
}
The problem is that #lesson containers do not fit inside the #container. How can I make that only 3 containers fit into one column? CSS ninjas, I need your help :)
My CSS: #container - main container, #first - green container, #lesson- gray divs.
#container {
position: relative;
top: 70px;
left: 80px;
width:100%;
height:80%;
}
#first {
background-color: #A1D490;
width:45%;
height:100%;
float:left;
border:2px solid black;
margin: 5px;
}
.lesson {
position: relative;
background-color: #DCDDDE;
margin:10px;
width:200px;
height:200px;
border:1px solid;
text-align: center;
}
HTML:
<div id="container">
<div id="first">
<tpl for=".">
<div class="lesson"; >
<p class="txt"><b>Lesson:</b> {lesson} </p>
<p class="txt"><b>Score:</b> {score}</p>
</div>
</tpl>
</div>
<div id="second">
</div>
</div>
For fitting the containers on the big one you just need to remove the height 100% from the id first
#first { /* height: 100% */ }
Codepen http://codepen.io/noobskie/pen/dYGLeo
It seems to be working fine for me here. Are you sure you dont have any other css being applied and overwriting rules somewhere?
HTML
<div id="container">
<div id="first">
<div class="lesson">
<p class="txt"><b>Lesson:</b> {lesson} </p>
<p class="txt"><b>Score:</b> {score}</p>
</div>
<div class="lesson">
<p class="txt"><b>Lesson:</b> {lesson} </p>
<p class="txt"><b>Score:</b> {score}</p>
</div>
<div class="lesson">
<p class="txt"><b>Lesson:</b> {lesson} </p>
<p class="txt"><b>Score:</b> {score}</p>
</div>
<div class="lesson">
<p class="txt"><b>Lesson:</b> {lesson} </p>
<p class="txt"><b>Score:</b> {score}</p>
</div>
</div>
</div>
CSS
#container {
position: relative;
top: 70px;
left: 80px;
width:100%;
height:80%;
}
#first {
background-color: #A1D490;
width:45%;
height:100%;
float:left;
border:2px solid black;
margin: 5px;
}
.lesson {
position: relative;
background-color: #DCDDDE;
margin:10px;
width:200px;
height:200px;
border:1px solid;
text-align: center;
}
I have two columns, in the left column I have made the .title extend the full width of the screen using negative margins.
On the right column I have .sidebar I would like this to appear below the extented .title div. Run the code snippet below and you'll see it starts on the same line. In other words I want the orange div to fall below the yellow div.
I don't want to use margin-top on the .sidebar because the height of .title in the left column varies.
I realise this is possible with javascript but I'm looking for a more robust solution just using html and css, is this possible?
I also created a fiddle if that's more convenient http://jsfiddle.net/2dLaw17r/1/
.container {
width:600px;
margin:0 auto;
clear:both;
padding:1em;
background:grey;
}
.left {
float:left;
width:60%;
}
.left .title {
margin:0 -500%;
padding:0 500%;
background: yellow;
}
.right{
float:right;
width:40%;
background:orange;
}
.clearfix:after {
content: "";
display: table;
clear: both;
}
<div class="container clearfix">
<div class="left">
<article>
<div class="title">Title extends beyond container</div>
<p>lorem ipsum someip orlem lorem ipsum someip orlem lorem ipsum someip orlem</p>
<article>
</div>
<div class="right">
<div class="sidebar">items in this sidebar div should fall below the title div. Currently it starts on the same line.</div>
</div>
</div>
Place a div inside the article that contains the article content. This way the title and content both remain inside the article. Next, float the article content left and the sidebar towards the right. The negative margin trick is no longer required:
.container {
width: 600px;
margin: 0 auto;
clear: both;
padding: 1em;
background: grey;
}
.title {
background: yellow;
/* eye candy only */
margin: 0 -1em;
padding: 0 1em;
}
.left {
float: left;
width: 60%;
}
.right {
float: right;
width: 40%;
background: orange;
}
.clearfix:after {
content: "";
display: table;
clear: both;
}
<div class="container clearfix">
<article>
<div class="title">Title extends beyond container<br>And can grow in height</div>
<div class="content left">
<p>lorem ipsum someip orlem lorem ipsum someip orlem lorem ipsum someip orlem</p>
</div>
</article>
<div class="sidebar right">
<p>items in this sidebar div should fall below the title div. Currently it starts on the same line.</p>
</div>
</div>
Issue is with your design and not CSS...if you plan your layout carefully you can avoid those negative margins altogether.Possible solution is suggested from my side is as below :
Redesign your markup and rename classes in more helpful manner :
working fiddle with updated markup
HTML
<div class="container clearfix">
<div class="left">
<div class="title">Title extends beyond container</div>
<div class="right">
<div class="sidebar">items in this sidebar div should fall below the title div. Currently it starts on the same line.</div>
</div>
<p>lorem ipsum someip orlem lorem ipsum someip orlem lorem ipsum someip orlem</p>
</div>
</div>
CSS
html, body { /* always mention this in you CSS - rule of Thumb for CSS */
width:100%;
height:100%;
margin:0;
padding:0
}
.container {
width:100%; /* stretch div to take full width of parent - HTML, BODY*/
margin:0 auto;
clear:both;
padding:1em;
background:grey;
}
.left {
/* float:left;*/ /* not needed with updated layout :) */
width:100%;
}
.left .title {
/*margin:0 -500%;
padding:0 500%; /* nightmare is removed */ */
width:100%;
background: yellow;
}
.right {
float:right;
width:40%;
background:orange;
}
.clearfix:after {
content:"";
display: table;
clear: both;
}
Like Antoine says, you have to put the title, outside the left div.
.container {
width:600px;
margin:0 auto;
clear:both;
padding:1em;
background:grey;
}
.left {
float:left;
width:60%;
}
.title {
background: yellow;
}
.right{
float:right;
width:40%;
background:orange;
}
.clearfix:after {
content: "";
display: table;
clear: both;
}
<div class="container clearfix">
<div class="title">Title extends beyond container</div>
<div class="left">
<p>lorem ipsum someip orlem lorem ipsum someip orlem lorem ipsum someip orlem</p>
</div>
<div class="right">
<div class="sidebar">items in this sidebar div should fall below the title div. Currently it starts on the same line.</div>
</div>
</div>
You have to clear floats like:
.container {
width:600px;
margin:0 auto;
clear:both;
padding:1em;
background:grey;
}
.left {
float:left;
width:60%;
}
.left .title {
margin:0 -500%;
padding:0 500%;
background: yellow;
}
.right{
float:right;
width:40%;
background:orange;
clear: left;/*add clear left*/
margin-top: -60px;/*add negative top margin*/
}
.clearfix:after {
content: "";
display: table;
clear: both;
}
<div class="container clearfix">
<div class="left">
<div class="title">Title extends beyond container</div>
<p>lorem ipsum someip orlem lorem ipsum someip orlem lorem ipsum someip orlem</p>
</div>
<div class="right">
<div class="sidebar">items in this sidebar div should fall below the title div. Currently it starts on the same line.</div>
</div>
</div>
Using CSS, I want to horizontally center two "boxes" I have within a div. The boxes are absolutely positioned.
Here is the JSFiddle: http://jsfiddle.net/p4sA3/8/
How would I achieve this without using specific widths?
HTML:
<button id="change">Change</button>
<div id="total-wrap">
<div id="hello-wrap" class="bunch">
<div id="box">
<p> Hello, this is text1 </p>
</div>
<div id="box">
<p> Hello, this is text2 </p>
</div>
</div>
<div id="goodbye-wrap" class="bunch">
<div id="box">
<p> Goodbye, this is text1 </p>
</div>
<div id="box">
<p> Goodbye, this is text2 </p>
</div>
</div>
</div>
CSS:
#total-wrap {
border:1px solid #000;
height:500px;
}
#box {
position:relative;
display:inline-block;
width:300px;
height:100px;
background-color:yellow;
margin:10px;
}
.bunch {
position: absolute;
text-align:center;
}
I would do it with left:0; and right:0 as they are absolutely positioned.
DEMO http://jsfiddle.net/kevinPHPkevin/p4sA3/19/
.bunch {
position: absolute;
text-align:center;
left:0;
right:0;
}
Solution:
#total-wrap {
border:1px solid #000;
height:500px;
}
#box {
display:inline-block;
width:300px;
height:100px;
background-color:yellow;
margin:10px;
text-align:center;
}
.bunch {
text-align:center;
}
<div id="wrap">
<div id="left">Box1</div>
<div id="right">Box2</div>
</div>
#wrap {
background: #e7e7e7;
padding: 40px;
text-align: center;
width: auto;
}
#left, #right {
background: yellow;
display: inline-block;
padding: 20px;
}
Is this what you want?
#box {
position:relative;
display:inline-block;
width:100px;
height:100px;
background-color:yellow;
margin:10px;
}
DEMO: http://jsfiddle.net/p4sA3/11/
The thing is that as long the sum of the widths exceeds the container, the second div will be positioned beneath the first one
In this other demo I didn't use width: http://jsfiddle.net/p4sA3/13/
If you want to use jQuery:
Demo
keepCentered = function() {
$('#hello-wrap').css({'margin-left':($('#total-wrap').width()-$('#hello-wrap').width())/2});
$('#goodbye-wrap').css({'margin-left':($('#total-wrap').width()-$('#goodbye-wrap').width())/2});
}
$(document).ready(keepCentered);
$(window).bind('resize', keepCentered);