Horizontal slider gets pushed down from page in react-bootstrap - html

So I am creating an application with a sidebar and topbar where the content on the right side changes and the sidebar and topbar are fixed. Now I want to create a page where I can put a horizontal carousel / slider for cards, but this gets pushed down for some rease. I don't think it has anything to do with the cards, but only with the slider since one card gets displayed correctly.
Page with slider]1 and Page with 1 card, ideally the slider should be on the same space where the card is displayed. I think it has something to do maybe with the react-bootstrap Col but I am not sure.
Page.js
const array = [...Array(50).keys()];
return (
<Container fluid className="justify-content-between align-content-between mt-0 mt-lg-4">
<Row>
<Col lg="9" m="4" className="mt-4 mt-lg-0">
<div>
<Slider items={array} />
</div>
</Col>
</Container>
)
Slider.js
return (
<div className="slider">
{ items.map((item, index) => (
<div key={index} className="slider-card-wrapper">
{/*<div>lol</div>*/}
<ProductCard />
</div>
)) }
</div>
)
Slider.css
.slider {
display : -webkit-box;
overflow-x : scroll;
overflow-y : hidden;
border-radius : 5px;
}
.slider-card-wrapper {
margin-left : 10px;
margin-right : 10px;
}
ProductCard.js
return (
<Card className="product-card">
{ isIMG &&
<div className="product-card-img">
<Card.Img variant="top" className="product-card-img" src="" />
<div className="product-card-img-overlay"/>
<div className="product-card-img-text">
text
</div>
</div>
}
<Card.Body className="product-card-body">
body
body
<br/>
body
</Card.Body>
<div className="product-card-divider" />
<Card.Footer className="product-card-footer">
<Link className="product-card-footer-link" to="/dashboard/product">
VIEW ITEM
</Link>
</Card.Footer>
</Card>
)
ProductCard.css
.product-card {
max-height : 400px;
max-width : 250px;
border-radius : 10px 10px 5px 5px;
border : 0;
-webkit-box-shadow: 0 0 14px #e7e7e7;
box-shadow: 0 0 14px #e7e7e7;
word-wrap : break-word;
}
.product-card-img {
position : relative;
border-radius : inherit;
border-color : transparent;
}
.product-card-img-actual {
display : block;
overflow : hidden;
border-radius : inherit;
}
.product-card-img-overlay {
position : absolute;
text-align : left;
left : 0;
right : 0;
top : 0;
bottom : 0;
border-radius : inherit;
background : #1f1f1fff;
opacity : 0.15;
}
.product-card-img-text {
margin-left : 10px;
margin-bottom : 10px;
}
.product-card-body {
text-align : center;
}
.product-card-footer {
text-align : center;
justify-content : center;
border-top-width : 3px;
border-color : #e0e0e0;
background : transparent;
}
.product-card-footer-link {
color : #008d74;
text-decoration : None;
font-weight : bold;
margin-top : 2px;
margin-bottom : 2px;
}
Sidebar.js
return (
<div className={classNames("sidebar", {"open" : isSidebarOpen})}>
<ChevronDoubleLeftIcon
className={classNames("sidebar-toggle", {"closed" : !isSidebarOpen})}
onClick={onSideBarOpen}
/>
<Nav className="flex-column">
{ routes.map((route, index) => (
route.sub_routes ?
<SidebarMenu
key={index}
data={route}
/>
:
<SidebarItem
key={index}
text={route.name}
icon={route.icon}
path={route.path}
/>
)) }
</Nav>
</div>
)
Sidebar.css
.sidebar {
min-width: 230px;
max-width: 240px;
height : 100vh;
margin-left: -200px;
background: #f7f9fb;
transition: all .5s;
}
.sidebar.open {
margin-left: -10px;
transform: scale(1);
transition: .5s;
}
.sidebar-item {
display: inline-flex;
margin-top: 1em;
color: #000000;
font-weight: bold;
}
.sidebar-item:hover {
background-color: #f2f4f7;
}
.sidebar-menu {
color: #000000;
font-weight: bold;
margin-top: 1em;
}
.sidebar-menu-item {
color: #000000;
font-weight: bold;
margin-top: 0.75em;
margin-left: 1.75em;
}
.sidebar-menu-item:hover {
background-color: #f2f4f7;
}
.sidebar-menu-icon {
color: #000000;
}
.sidebar-toggle {
position: relative;
height: 1.25em;
width: 1.25em;
top: 10px;
left: 0px;
z-index: 999;
float: right;
background-color: #f7f9fb;
color: #000000;
cursor: pointer;
border-radius: 0px .25em .25em 0px;
transition: transform .5s ease-in-out;
}
.sidebar-toggle.closed {
transform-origin: center;
transform: translateX(-0px) rotate(180deg) ;
}
.nav-item {
color: #000000;
font-weight: bold;
}
.nav-link {
color: #000000;
font-weight: 600;
max-width: 190px;
overflow: hidden;
text-overflow: ellipsis;
}
.sidebar-icon {
color: #000000;
width: 1.25em;
height: 1.25em;
margin-right: 0.75em;
}
Topbar.js
return (
<Navbar bg="light" expand="lg" sticky="top">
<Container fluid>
<Navbar.Brand href="#">PPDB</Navbar.Brand>
<Navbar.Toggle aria-controls="navbarScroll"/>
<Navbar.Collapse id="navbarScroll">
<Nav
className="me-auto my-2 my-lg-0 justify-content-center"
style={{maxHeight: '100px'}}
navbarScroll
>
<Nav.Link href="Dashboard">Home</Nav.Link>
</Nav>
<Form className="d-flex">
<FormControl
type="search"
placeholder="Search"
className="me-2"
aria-label="Search"
/>
</Form>
</Navbar.Collapse>
</Container>
</Navbar>
)
Layout.js
return (
<div>
<Container fluid className={"h-100"} style={{paddingLeft : "0px", paddingRight : "0px"}}>
<Topbar />
<Row className={"h-100"}>
<Sidebar />
<Col>
<Suspense fallback={<Spinner animation="border" role="status" />}>
<Routes>
<Route path='/' element={<h1> BASE </h1>} />
{ routes.map((route, index) => (
route.sub_routes ?
route.sub_routes.map((sub_route, i) => (
<Route
path={sub_route.path}
key={i}
element={<sub_route.component />}
/>
))
:
<Route
path={route.path}
key={index}
element={<route.component />}
/>
)) }
</Routes>
</Suspense>
</Col>
</Row>
</Container>
</div>
)

You overuse Grid there (like many other people do), as you do not have a real two-dimensional layout. I would strongly recommend to stick to flexbox as much as possible. There is a component for it in react-bootstrap called Stack. Using only Stack you will come very far. In your case I would layout application only with this component:
Look into following sandbox: https://codesandbox.io/s/clever-elion-frb220. I have provided colors, ids, names and some padding, so you can see how this layout is structured:
Upper Stack is vertical, for stacking top appbar/navbar and the rest of your application
Lower Stack is horizontal, for stacking sidebar(probably with fixed width) and the content section
Regarding your problem: In your Layout component you define a Row, but do not define Cols everywhere - the imported Sidebar component is not a Col.
Grid is for example useful when:
You have table like structure (two-dimensional)
You want to define responsive design with different layout on some breakpoints
You want to work with offsets, so things are aligned consistently.

Related

How to prevent absolute element from going off screen?

I'm setting up some conceptual functions (hence the probably botched way this is put together), but I'm running into an unforeseen issue with using position : absolute on the toast elements. On the right-hand products there's no issue besides the toast overlapping the products to its left (which is fine in this case), but when it triggers on the left column it extends outside the viewport.
That's why the class="diamond" is outside the toast itself, so that it can remain static regardless of the toast's position, since I assume position : absolute is not the ideal positioning for the toast.
So my question is, how can I achieve the intended effect of the toast triggering but remaining inside the viewport? My intention is for the diamond to be "anchored" to the button, with the toast itself dynamic on the horizontal axis.
Click the red square to open the toast, and the green one inside to close it.
function open(event) {
if (!event.target.closest(".product button")){
return false;
}
const parent = event.target.closest(".product");
const toast = parent.querySelector('.toast');
const diamond = parent.querySelector('.diamond');
toast.style.display = 'block';
diamond.style.display = 'block';
}
function close(event) {
if (!event.target.closest(".toast button")){
return false;
}
const product = event.target.closest(".product");
const toast = event.target.closest(".toast");
product.querySelector('.diamond').style.display = 'none';
toast.style.display = 'none';
}
addEventListener('click', open);
addEventListener('click', close);
.container {
display : flex;
flex-flow: row wrap;
justify-content : space-around;
height : 450px;
width : 300px;
background-color : grey;
}
.product {
position : relative;
height : 200px;
width : 130px;
background-color : blue;
}
.icon {
position : absolute;
top : 10px;
right : 10px;
height : 30px;
width : 30px;
background-color : red;
}
.diamond {
position : absolute;
display : none;
height : 10px;
width : 10px;
top : 50px;
right : 20px;
background-color : black;
transform : rotate(45deg);
}
.toast {
position : absolute;
display : none;
width : 160px;
height : 50px;
top : 55px;
right : 10px;
background-color : black;
border-style: solid;
border-width : thin;
border-color : red;
}
.close {
position : absolute;
display : block;
width : 20px;
height : 20px;
top : 15px;
right : 70px;
background-color : green;
}
<div class="container">
<div class="product">
<button class="icon"></button>
<div class="diamond"></div>
<div class="toast">
<button class="close"></button>
</div>
</div>
<div class="product">
<button class="icon"></button>
<div class="diamond"></div>
<div class="toast">
<button class="close"></button>
</div>
</div>
<div class="product">
<button class="icon"></button>
<div class="diamond"></div>
<div class="toast">
<button class="close"></button>
</div>
</div>
<div class="product">
<button class="icon"></button>
<div class="diamond"></div>
<div class="toast">
<button class="close"></button>
</div>
</div>
</div>
This can be the possible solution. Please replace toast css with the below css:
.toast {
position: absolute;
display: none;
width: 100%;
height: 50px;
top: 55px;
right: 0;
background-color: black;
border-style: solid;
border-width: thin;
border-color: red;
}
Hope this will help you!

How to change a svg image along with text with hover in CSS

I tried to change my svg image and text on hover and it doesn't work how I want it. I want the moment my mouse crosses over any of these 2 (svg or text) to change both.
Maybe I made a mistake in the html structure or maybe in css.
Please if you can help me, thanks in advance.
.logout-image {
mask: url("../../../assets/images/log-out.svg");
background-color: #62799D;
width: 20px;
height: 20px;
margin-right: 20px;
margin-left: 20px;
}
.logout-container {
display: flex;
flex-direction: row;
align-items: center;
padding: 8px 0px 8px 24px;
width: 100%;
height: 60px;
position: static;
left: 0px;
top: 280px;
color: #62799d;
margin-top: 35vh;
}
.logout-container:hover {
background: #0c2e6e;
color: white;
}
.logout-image:hover{
background: white;
}
<ul className="SidebarList">
{sidebarData.map((value, key) => {
return (
<li
className="row"
key={key}
onClick={() => {
window.location.pathname = value.link;
}}
>
{" "}
<div className="icon">{value.icon}</div>{" "}
<div className="title">{value.title}</div>
</li>
);
})}
{" "}
{" "}
//here is the problem
<li className='logout-container'>
<div className="logout-image"></div>
<div className="title" >Logo Out</div>
</li>
//until here
</ul>
This is how I wanted to change with hover:
target result
And this is how it is working right now:
current result
The background changes only if I cross over my svg image:
example here
Add this:
.logout-container:hover > .logout-image{
background: white;
}
It turns the image and words white when logout-container is hovered.

CSS unecessary space in main when in mobile mode

This is what the site is like when in desktop mode:
Now in mobile mode:
You can see that there is now extra space on the bottom. I make sure to erase margins everywhere but the space still remained there.
Pertinent css code:
.grid-container{
display: grid;
grid-template-areas:
"header"
"main"
"footer";
grid-template-columns: 1fr;
grid-template-rows: 5rem 1fr 3rem;
height: 100%;
}
.main {
grid-area: main;
background-image: url("res/background_min.jpg");
overflow: hidden
}
/*Home Screen*/
.home{
display: flex;
}
.menu-list{
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
height: 100%;
}
.menu-list a {
padding: 0rem;
flex: 0 1 50rem;
margin: 1.5rem;
height: 100%;
width: 100%;
display: flex;
text-decoration: none;
color: white;
}
.menu-list li
{
display: flex;
list-style-type: none;
text-decoration: none;
align-items: center;
justify-content: center;
width: 100%;
height: 10%;
}
.menu-list p {
font-size: 2vw;
}
.section a {
color: #ffffff;
font-weight: bold;
font-size: 2vw;
text-decoration: none;
}
.about {
background-image: linear-gradient(to right, cyan, magenta);
}
.contacts {
background-image: linear-gradient(to right, fuchsia, turquoise);
}
.projects{
background-image: linear-gradient(to right, turquoise, fuchsia);
}
.question-box {
background-image: linear-gradient(to right, magenta, aqua);
}
.home-main-image{
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
max-width: 45%;
}
.home-main-image img{
max-width: 99%;
}
.fade-in {
animation: fadeIn ease 2s;
}
.button{
background-image: linear-gradient(to right, cyan, magenta);
border: none;
text-align: center;
color: white;
text-decoration: none;
font-size: 1vw;
padding: .5rem;
}
Menu list is the vertical column of buttons that should occupy most of the screen on the left, and home-main-image is the giant terminal logo plastered on the right.
Note that the issue happens with a real mobile device too.
Edit: For clarification, this is the extra space:
Edit: added react html:
App.js
function App() {
const [lang, setLang] = useLanguage();
const handleLanguageChange = () => {
if (lang.lang === 'eng'){
setLang('fr')
} else {
setLang('en')
}
}
return (
<BrowserRouter>
<div className="grid-container">
<header className="header">
<div className="brand">
<Link to="/" >
Eduardo Breton
</Link>
</div>
<div className="header-side">
{lang.subtitle}
</div>
<div className="header-right">
<button className="button" onClick={() => handleLanguageChange()}>{lang.traduction} </button>
</div>
<div>
</div>
</header>
<main className="main">
<div className="content">
<Route path="/" exact={true} component={HomeScreen} />
<Route path="/about" component={AboutScreen}/>
<Route path="/contact" component={ContactScreen}/>
<Route path="/project" component={ProjectScreen}/>
<Route path="/question" component={QuestionScreen}/>
</div>
</main>
<footer className="footer">
© 2020 Eduardo Breton
</footer>
</div>
</BrowserRouter>
);
}
HomeScreen.js:
const { Link } = require("react-router-dom");
function HomeScreen() {
const [lang, setLang] = useLanguage();
return <div className="home">
<ul className="menu-list">
<Link to="/about">
<li className="fade-in section about" >
{lang.about}
</li>
</Link>
<Link to="/contact">
<li className="fade-in section about" >
{lang.contact}
</li>
</Link>
<Link to="/project">
<li className="fade-in section about" >
{lang.projects}
</li>
</Link>
<Link to="/question">
<li className="fade-in section about" >
{lang.question}
</li>
</Link>
</ul>
<div className="home-main-image fade-in">
<img src={terminalImage} />
</div>
</div>
}
export default HomeScreen;
Checked answer with the discussion has fixed the issue, changing flex-direction to column on a media screen on main has allowed me to center correctly the contents:
the first thing you need to do is add a meta description for mobile view in the head. These in particular
<meta content="width=device-width, initial-scale=1" name="viewport" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
Next you need to make your site responsive by adding media queries so that the home main image and your buttons become responsive. You should increase the size of the menu buttons and set them to
#media screen and (max-width:650px) {
.menu-list li {
flex-direction:column;
}
}
That way your buttons will be bigger, aligned in the center, AND in a column (this will look better on mobile). You should also change the flex direction of the main image. Also, try adding some padding between the buttons in mobile view, this should also help in taking up the space.

html element adaptable when browser window resize using bootstrap in html?

I need to use bootstrap for the div element with css changes. i tried with col-xs-* and col-md-* for the div but it not working. I need a help regarding when the browser resize it adaptable to the page.
HTML:
<body ng-controller="MainCtrl">
<div class="pull-right metrics-section ng-scope">
<span class="metrics-header-section col-sm-2 ng-scope"
ng-repeat="items in metrics">
<p class="ng-binding">{{items.value}}</p>
<p>{{items.name}}</p>
<p class=" metrics-divider"> </p>
</span> </div> </body>
.css:
.metrics-section {
background-color: #b6b5b5;
border-radius: 3px;
height: 31px;
margin-top: 0px;
}
.metrics-header-section {
font-size: 12px;
color: #003265;
width: 155px;
height: auto;
padding-top: 1px; }
.metrics-header-section p:not(.metric-divider) {
margin: 2px;
width: auto;
text-align: center;
display:block;
}
.metrics-header-section p:first-child {
font-size:13px;
color:#3D6186;
}
.metrics-header-section p:nth-child(2) {
font-size:9px;
color:#3D6186;
}
span.metrics-header-section > p.metrics-divider {
position: relative;
bottom: 25px;
border-right: 1px solid #003265;
height: 20px;
}
.metrics-header-section:nth-child(4) > p.metrics-divider {
position: relative;
bottom: 15px;
border-right: none;
height: 20px;
}
.js:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.metrics = [
{name : "COMPLETED", value : "12"},
{name : "EXCEEDING", value : "18"},
{name : "APPROACHING", value : "10"},
{name : "AVAILABLE", value : "40"}
];
});
The output as follows:
12 18 10 40
COMPLETED | EXCEEDING | APPROACHING | AVAILABLE
You need to load Boostrap's CSS, not just the Javascript. Add this to the <head> tag:
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">

Overriding listview item background in HTML- Windows Phone 8.1

I have the following template deisgned to display a listview. But the items in the list assign a background color of black by default. I am not able to override their BG color property. I have experience in native WP developement using C#. But in HTML 5 and WinJS am not able to figure out half the things about design.
HTML Code:
<div id="pivotScenario3" data-win-control="WinJS.UI.Pivot" data-win-options="{ selectedIndex: 4 }">
<div id="listViewMenu" class="listviewpivotitem" data-win-control="WinJS.UI.PivotItem" data-win-options="{ 'header': 'SPORTS' }">
<div data-win-control="WinJS.UI.ListView" data-win-options="{ itemDataSource: All.dataSource, layout: { type: WinJS.UI.ListLayout }, itemTemplate: menuItemTemplate, selectionMode: 'none' }"></div>
</div>
Template code:
<div id="menuItemTemplate" data-win-control="WinJS.Binding.Template">
<div class="menuItem">
<table>
<tr>
<td>
<img data-win-bind="src: logo" alt="Databound image" class="logo" />
</td>
<td>
<div class="selectionmodeHitTarget win-interactive"></div>
<div class="sportNameRoot">
<h2 class="sportName" data-win-bind="innerHTML: sportName"></h2>
</div>
</td>
</tr>
</table>
</div>
</div>
CSS:
.menuItem {
display: -ms-grid;
-ms-grid-columns: 20px 1fr 60px;
-ms-grid-rows: auto auto auto;
background-color: transparent;}
.menuItem .selectionmodeHitTarget {
/* So it is stacked on top of other grid elements */
position: relative;
z-index: 1;
-ms-grid-column: 1;
-ms-grid-row: 1;
-ms-grid-row-span: 3;
width: 16px; /* reserve 4px gap between highlight and item edge */
height: 100%;
transition: background-color 250ms ease-out 250ms, visibility 0ms linear 500ms, transform cubic-bezier(0.17,0.79,0.215,1.0025) 250ms;
}
.menuItem .selectionmodeHitTarget:active {
transition: background-color ease-out 100ms; /* fade in fast */
background-color: Highlight;
}
.menuItem .selectionmodeHitTarget:after {
margin: 0 16px;
width: 16px;
height: 100%;
content: '';
}
.win-selectionmode .menuItem .selectionmodeHitTarget {
transform: translateX(-41px); /* delayed by transition */
visibility: hidden;}
.win-selectionmode .win-item {
overflow: visible;}
CSS for pivot n listview
.listviewpivotitem.win-pivot-item .win-pivot-item-content {
/* Stretch across the whole width of the screen so the whole thing is pannable.*/
padding: 0;
margin: 0;
width: 100%;}
.win-listview {
height: 100%;}
#pivotScenario3 .win-listview .win-container {
margin: 0;
padding: 5px 0 0 0;
background-color: transparent;}
#pivotScenario3 .win-listview.win-rtl .win-item {
margin: 0 0 0 20px;}
#pivotScenario3{
color:white;}
My need is that, i want to set any desired color as background color for listview items.
I know this is a lot of code to go through but my problem is too complicated. Haven't found a solution since a week. This is my last resort.
All help, suggestions and answers are appreciated!
Bind color code with style property
like:
<div data-win-bind="style.background:Color"></div>
it will give you the expected result.
All the Best..!!