The difficult issue is that I need this CSS rule: html {height: 100%} in order to make my first page work. See prototype.
This allows the login div to be centered based on the height of the window.
However, the second page now is stuck at this height and does not expand as I populate the content using ajax. Either click on the star in this link or see below.
You can see where the dotted line stops is the original rendering of the window at 100%.
If I remove the height of 100% it will expand but then the SignOn page is broken as it has no height.
Note: React is controlling the changing from page to the other using a simple conditional in the JSX based on the application state.
Should I alter the CSS height for HTML based on application state or is there a better way to do this?
A better question, might be, that after the content in the div changes, shouldn't the div expand to reflect this?
Relevant CSS
html{
width: 100%;
height: 100%;
}
body{
background-image: url('_images/bg_paper.jpg');
height: 100%;
width: 100%;
}
#app{
width: 100%;
height: 100%;
}
#contents{
width: 100%;
height: 100%;
}
#top-1{
position: fixed;
width: 100%;
height: 40px;
background: rgba(255, 255, 255, 0.8);
border-top: 3px solid #000000;
border-bottom: 1px solid #bbbbbb;
z-index: 1000;
}
#top-2{
position: relative;
width: 90%;
height: 100%;
margin: 0 auto;
border-left: 1px dotted #888888;
border-right: 1px dotted #888888;
}
#container-1{
position: relative;
display: inline-block;
width: 100%;
height: 100%;
top: 44px;
}
#container-2{
position: relative;
width: 90%;
height: 100%;
margin: 0 auto;
border-left: 1px dotted #888888;
border-right: 1px dotted #888888;
}
.body{
display: none;
position: relative;
width: 100%;
height: 100%;
}
I think using flex is much easier to deal with this kind of situations.
You can set your main container as flex and play with the justify and align properties to center the elements.
The problem here is that you got a fixed positioned element as a toolbar that goes out of flow, so we will set margin-top to the next element respectively to the fixed element's height.
another issue is that you want to center the login component when its parent isn't at the same height as the view port, this can be handled with a min-height:100vh to the main container.
Here is a very basic demonstration of the above:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
login: true,
items: [
'item 1',
'item 2',
'item 3',
'item 4',
]
};
}
addITem = e => {
const { items } = this.state;
const nextItem = `item ${items.length + 2}`;
this.setState({ items: [...items, nextItem] });
}
loginView = e => {
this.setState({ login: true });
}
login = e => {
this.setState({ login: false });
}
render() {
const { items, login } = this.state;
return (
<div className="container">
<div className="toolbar">
<div className="title">This is a fixed toolbar, click to add items</div>
<button className="btn" onClick={this.addITem}>+</button>
<button className="btn" onClick={this.loginView}>Login</button>
</div>
{login ?
<div className="login-wrapper">
<div className="login">
<label>Login</label>
<input placeHolder="user name" />
<input type="password" placeHolder="password" />
<button className="btn" onClick={this.login}>Go</button>
</div>
</div>
:
<div className="items">
{items.map(item => <div className="item">{item}</div>)}
</div>
}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
.container {
display: flex;
flex-direction: row;
min-height: 100vh;
}
.toolbar {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border: 1px solid #ccc;
padding: 10px;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 999;
background-color: #333;
color: #fff;
}
.title {
padding: 10px;
}
.btn {
padding: 5px;
width: 100px;
margin: 0 15px;
}
.items {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-top: 65px;
align-content: baseline;
}
.item {
display: flex;
justify-content: center;
align-items: center;
height: 50px;
width: 250px;
box-shadow: 0 0 3px 1px #333;
margin: 5px;
padding: 5px;
}
.login-wrapper{
display: inline-block;
margin: auto;
}
.login {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Related
I have tried looking around for this but can't seem to find a question to match my current problem. I am trying to build a mock ecommerce website to practice using React. I have a header component. I want this component to be 100% of the screen width, so that the elements inside this component shrink whenever the page shrinks. I have some global css that sets the height and width of the html and body to 100%:
html, body{
background-color: rgb(167, 72, 72);
height: 100%;
min-width: 100%;
}
I am currently facing two problems, neither of which I understand very well the causes of. When I set my header component (the outermost component) to have a width of 100%, the page shrinks correctly. But when I open up developer tools to check the responsiveness, something goes wrong so that the right side of my header is shrinking faster than the page header_shrink
I am able to fix this by setting the width of my header to "fit-content" instead of "100%". Here is what the header looks like when I shrink the page using developer tools.header_fixed But when I do it this way, the components inside of my header don't shrink correctly. For example, my search bar is supposed to decrease in width as I shrink the page, but when I use "fit-content", it just stays set to whatever size it is. search-bar-constant. When I have the width set to 100% instead of fit content, it looks the way it's supposed to search-bar-fixed.
Sorry for the long explanation, but this is the bulk of my problem. "Width: 100%" allows the items in my header component to shrink correctly, but not the component itself. And "width: fit-content" allows the outer header component to shrink correctly, but not the items inside of it.
Here is the JSX I have for reference:
import React from 'react'
import './Header.css'
import { BiSearchAlt2 as SearchIcon} from "react-icons/bi";
import {RiArrowDropDownLine as DropDownIcon} from "react-icons/ri";
import { CgProfile as Profile } from "react-icons/cg";
import { CgShoppingCart as Cart } from "react-icons/cg";
const Header = () => {
const texts = [
'ORDERS OF $5K SHIP FREE',
'FREE SHIPPING ON SELECT ITEMS: SHOP NOW',
'BUY A RIG AND YOUR ENTIRE ORDER SHIPS FREE'
];
let currentTextIndex = 0;
setInterval(() => {
const shippingDealsText = document.querySelector('.shipping-deals-text');
shippingDealsText.classList.add('out');
setTimeout(() => {
shippingDealsText.textContent = texts[currentTextIndex];
shippingDealsText.classList.remove('out');
currentTextIndex = (currentTextIndex + 1) % texts.length;
}, 1000);
}, 5000);
return (
<div className="header">
<div className="header-top">
<div className="top-logo">
<h5 className='small-logo'>LEVIATHAN</h5>
</div>
<div className="space"></div>
<div className="link-container">
<div className="link-wrap">
Gift Cards
</div>
<div className="link-wrap">
Contact Us
</div>
<div className="link-wrap">
Order Status
</div>
<div className="link-wrap">
Live Chat
</div>
</div>
</div>
<div className="header-middle">
<div className="middle-logo">
<h5 className='big-logo'>LEVIATHAN</h5>
</div>
<div className="search-container">
<div className="search-wrapper">
<input
type="text"
id="search-bar"
placeholder="Search"
className='search'
/>
<div className="search-icon-wrapper">
<SearchIcon className='search-icon'/>
</div>
</div>
</div>
<div className="shipping-deals-container">
<div className="button-container">
<div className="shipping-deals-button">
<span className="deals-text">DAILY SHIPPING DEALS </span>
</div>
</div>
<div className="text-container">
<div className="text-slideshow">
<p className="shipping-deals-text">BUY A RIG AND YOUR ENTIRE ORDER SHIPS FREE</p>
</div>
</div>
</div>
<div className="icons-right">
<Profile className='login-pic'/>
<span>Log In</span>
<Cart className='shopping-cart'/>
</div>
</div>
<div className="header-bottom">
<div className="nav-bar">
<ul className='navigation'>
<li className='menu-items'>
<a href="/" className='button drop-down red'>Shop <DropDownIcon className='drop-icon'/></a>
<a href="/" className='button'>Equipment for Crossfit</a>
<a href="/" className='button'>New Gear</a>
<a href="/" className='button'>Barbells</a>
<a href="/" className='button'>Plates</a>
<a href="/" className='button'>Rigs and Racks</a>
<a href="/" className='button'>Shoes</a>
<a href="/" className='button'>Apparel</a>
<a href="/" className='button'>3 Ships Free</a>
<a href="/" className='button'>Zeus</a>
<a href="/" className='button drop-down'>The Index</a>
</li>
</ul>
</div>
</div>
</div>
)
}
export default Header
Here is the styling I am currently applying:
.header {
min-width: 100%;
margin: 0;
padding: 0;
}
.header-top {
background-color: white;
display: flex;
height: 2.5rem;
width: 100%;
}
.top-logo {
position: relative;
margin-left: 3rem;
}
.space {
flex-grow: 1;
}
.small-logo {
padding-top: 0.5em;
position: relative;
font-size: larger;
color: rgb(133, 133, 133)
}
.link-container {
display: flex;
/*border: 1px solid red;*/
margin-right: 3rem;
}
.link-wrap {
/*border: 1px solid green;*/
font-size: 14px;
padding-left: 1rem;
padding-top: 0.75rem;
}
.link-wrap a {
text-decoration: none;
color:#666666;
cursor: pointer;
}
/* Large section of header, black background */
.header-middle {
background-color: black;
height: 7rem;
display: flex;
}
/* Big LEVIATHAN text */
.middle-logo {
/*border: 1px solid red;*/
position: relative;
margin-left: 3rem;
display: flex;
justify-content: center;
align-items: center;
cursor: co;
}
.big-logo {
font-size: 48px;
/*padding-top: 2rem;*/
position: relative;
color: white;
}
.big-logo:hover {
color: rgb(210, 0, 0);
}
.search-container {
position: relative;
width: 40%;
display: flex;
flex-basis: 60%;
margin-left: 3rem;
align-items: center;
justify-content: center;
}
/*This is what has the appearance of the search bar*/
.search-wrapper {
min-width:100%;
height: 35%;
position: relative;
background-color: white;
display: flex;
flex-basis: 50%;
}
.search-icon-wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 3rem;
}
.search-icon {
color: black;
font-size: 20px;
}
/*This is the actual search bar tucked inside*/
.search {
width: 100%;
height: 100%;
border: none;
outline: none;
margin-left: 1em;
font-size: 17px;
}
.search::placeholder {
color:rgb(94, 94, 94);
}
/* This holds onto both our daily shipping deals button */
/* and our text slideshow */
.shipping-deals-container{
width: 18em;
margin-left: 2.5em;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
/*border: 2px solid rgb(136, 77, 255);*/
}
.shipping-deals-button {
width: 65%;
height: 44%;
background-color: rgb(234, 2, 2);
position: relative;
display: flex;
justify-content: center;
align-items: center;
margin-top: 1.5em;
}
.button-container {
width: 100%;
height: 50%;
/*border: 2px solid magenta;*/
}
.deals-text {
color: white;
font-size: 12px;
position: relative;
text-align: center;
align-items: stretch;
width: 100%;
}
.text-container {
/*border: 2px solid rgb(20, 182, 11);*/
width: 100%;
height: 50%;
}
.text-slideshow {
color: white;
width: 100%;
height: 50%;
font-size: 12px;
}
.shipping-deals-text {
transition: opacity 1s;
opacity: 1;
font-size: 13px;
}
.out {
opacity: 0;
transition: opacity 1s;
}
.shipping-deals-text-red{
color: red;
}
.navigation {
display: flex;
align-items:flex-start;
height: 3rem;
}
.menu-items {
height: 100%;
margin-left: 1.5rem;
padding-right: 1.5rem;
display: flex;
align-items: flex-start;
flex: 1;
}
ul {
list-style-type: none;
background-color: #333333;
}
.button {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
text-decoration: none;
color: white;
text-transform: uppercase;
white-space: nowrap;
padding: 1em;
font-weight: bold;
}
.button:hover {
color:rgb(210, 0, 0)
}
.red {
background-color: rgb(210, 0, 0);
}
.red:hover {
color: white;
}
.drop-icon {
font-size: 25px;
}
.icons-right {
height: 50%;
margin-top: 2em;
min-width: 10%;
display: flex;
justify-content: center;
align-items: center;
margin-right: 1rem;
}
.login-pic {
color: white;
font-size: 20px;
}
.shopping-cart {
color: white;
font-size: 20px;
margin-left: 1rem;
}
.icons-right span {
color: white;
margin-left: 0.5em;
}
#media (max-width: 1025px) {
.shipping-deals-container {
display: none;
}
.header-top {
display: none;
}
.header-middle {
height: 50%;
}
.search-wrapper {
border: 2px solid white;
height: 2rem;
}
.icons-right {
margin-bottom: 2rem;
}
}
I have tried altering the width of my body, and html, but nothing seems to be giving me the solution I am looking for
With width: 100% on .header it shrinks the header the way you want it. That seems to be correct actually.
The element that prevents shrinking is <li class="menu-items"></li> because of display: flex;. Flexbox is by default not wrapping (flex-wrap: nowrap;).
Add flex-wrap. wrap; and you'll see everything will shrink with fit-content or width: 100%;
Hope this helps.
On another note: You shouldn't use <li> (List-Element) as the list. Thats what <ul> (Unsorted list) is for.
It should look more like this ->
<ul>
<li>
Shop
</li>
<li>
Equipment for Crossfit
</li>
<li>
New Gear
</li>
<!-- ... -->
</ul>
I make a game for a project that you must find the real neighbours of a country.
I have this HTML code:
.game-panel {
gap: 10px;
display: grid;
grid-template-columns: 200px auto;
grid-template-rows: 5.5em 22px auto;
gap: 10px;
grid-template-areas: "side main" "side main2" "side main3";
}
#sidebar {
width: 200px;
border-radius: 5px;
background-color: #ff1493;
display: flex;
grid-area: side;
flex-direction: column;
z-index: 100;
}
#playing-country {
display: flex;
border-radius: 5px;
background-color: #708090;
grid-area: main;
}
#progress {
-webkit-appearance: none;
display: flex;
position: sticky;
top: 0;
height: 24px;
grid-area: main2;
height: 24px;
border: 1px solid #ccc;
color: #aaa;
width: 100%;
border-radius: 5px;
z-index: 102;
}
#progress[value]::-webkit-progress-bar {
background: #f1f1f1;
}
#progress[value]::-webkit-progress-value {
background: blue;
}
#neighbours-panel {
border-radius: 5px;
grid-area: main3;
display: flex;
flex-shrink: 1;
background-color: #fff;
}
.overlay {
position: absolute;
padding: 0 !important;
margin: 0 !important;
background-color: rgba(136, 132, 132, 0.5);
}
<div class="game-panel">
<div id='sidebar'>
<h3>Βρες τους γείτονες</h3>
<div id="round">Γύρος: <span id='round-text'>0</span></div>
<div id="score">Σκορ: <span id='score-text'>0</span></div>
<button id="btn-next-round"><span>Επόμενη χώρα</span></button>
<button id="btn-new-game"><span>Νέο παιχνίδι</span></button>
</div>
<div id="playing-country">playing-country</div>
<progress id='progress' max='100' value='0'></progress>
<div id='neighbours-panel'>
</div>
</div>
In the #neighbours-panel I dynamically create divs with country choices and when I click the right ones, a semi-transparent div with overlay class is created inside the #neighbours-panel that covers only the #neighbours-panel with the countries. To do this I add position:relative; to the parent #neighbours-panel and position:absolute; to the newly created overlay div. The #progress must be sticky on the top of the page when scroll down. The problem is that with position:relative; on the #neighbours-panel in order to work properly the overlay, the position:sticky; of the #progress is disabled. If I remove position:relative; then the sticky position works as it should but then the overlay div covers the whole page and not only the #neighbours-panel as it should. Can anyone help me find out what to do?
I want to create a dynamic tile(div) based on number of users are available.
Like it is happen in microsoft team meetings.
Example -
when there is only user then div occupy full screen.
When there are two users then both the divs should get 50% width like
When there are 3 users then divs should occupy 25%,25% and 50% area of screen. Like
When there ate four, five and six user then it will occupy space as -
And so on. So the dynamic tile (div) can adjust the UI automatically atleast upto 12-16 tiles.
This also needs to be responsive.
Any help is really appreciated.
I made one to three users.
This is an example. using the current logic, you can do the rest yourself.
good luck.
var numUsers = $('#xusersx .user').length;
$('#xusersx').addClass('nowusers-' + numUsers);
body {
margin: 20px;
}
#xusersx {
display: flex;
width: 100%;
flex-wrap: wrap;
justify-content: space-between;
}
#xusersx>.user {
border: solid 4px black;
box-sizing: border-box;
}
#xusersx.nowusers-1>.user {
width: 100%;
height: 200px;
}
#xusersx.nowusers-2>.user, #xusersx.nowusers-3>.user {
width: calc(50% - 10px);
height: 200px;
}
#xusersx.nowusers-3 {
width: 50%;
}
#xusersx.nowusers-3>.user:last-child {
width: 100%;
height: 160px;
margin-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<div id="xusersx">
<div class="user"></div>
</div>
var numUsers = $('#xusersx .user').length;
$('#xusersx').addClass('nowusers-' + numUsers);
body {
margin: 20px;
}
#xusersx {
display: flex;
width: 100%;
flex-wrap: wrap;
justify-content: space-between;
}
#xusersx>.user {
border: solid 4px black;
box-sizing: border-box;
}
#xusersx.nowusers-1>.user {
width: 100%;
height: 200px;
}
#xusersx.nowusers-2>.user, #xusersx.nowusers-3>.user {
width: calc(50% - 10px);
height: 200px;
}
#xusersx.nowusers-3 {
width: 50%;
}
#xusersx.nowusers-3>.user:last-child {
width: 100%;
height: 160px;
margin-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<div id="xusersx">
<div class="user"></div>
<div class="user"></div>
</div>
var numUsers = $('#xusersx .user').length;
$('#xusersx').addClass('nowusers-' + numUsers);
body {
margin: 20px;
}
#xusersx {
display: flex;
width: 100%;
flex-wrap: wrap;
justify-content: space-between;
}
#xusersx>.user {
border: solid 4px black;
box-sizing: border-box;
}
#xusersx.nowusers-1>.user {
width: 100%;
height: 200px;
}
#xusersx.nowusers-2>.user, #xusersx.nowusers-3>.user {
width: calc(50% - 10px);
height: 200px;
}
#xusersx.nowusers-3 {
width: 50%;
}
#xusersx.nowusers-3>.user:last-child {
width: 100%;
height: 160px;
margin-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<div id="xusersx">
<div class="user"></div>
<div class="user"></div>
<div class="user"></div>
</div>
I tried to make a site with a resizable sidebar using jquery-resizable.js. What I want to do is making stop resizing once it reaches the specific width. However, it keeps moving even though it is already over the min-width value. I found the ResizeObserver to detect the changing width values and tried to change the div element's CSS values like resize:none; but it didn't work.
How could I stop resizing once it reaches a certain width value?
Here are my codes.
$(".panel-left").resizable({
handleSelector: ".splitter",
resizeHeight: false,
resizeHeightFrom:'center',
});
var ro = new ResizeObserver(entries => {
for (let entry of entries) {
const cr = entry.contentRect;
console.log('Element:', entry.target);
console.log(`Element size: ${cr.width}px x ${cr.height}px`);
console.log(`Element padding: ${cr.top}px ; ${cr.left}px`);
if (cr.width <= 330) {
console.log("its too small");
cr.css('resize', 'none');
}
}
});
ro.observe(document.querySelector('.panel-right'));
.panel-container {
display: flex;
flex-direction: row;
border: 1px solid silver;
overflow: hidden;
}
.panel-left {
flex: 0 0 auto;
padding: 10px;
width: 900px;
/* min-height: 100%; */
min-width: 650px;
white-space: nowrap;
background: #8E44AD;
color: white;
}
.panel-right {
flex: 1 0 auto;
padding: 10px;
width: 300px;
/* min-height: 100%; */
min-width: 350px;
background: #34495E;
color: #fff;
overflow-x: hidden;
}
.splitter {
flex: 0 0 auto;
width: 8px;
background: url(images/vsizegrip.png) center center no-repeat #ccc;
min-height: 100%;
cursor: col-resize;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.jqueryscript.net/demo/jQuery-Plugin-To-Generate-Resizable-DOM-Elements-Resizable/src/jquery-resizable.js"></script>
<div class="panel-container el" style="height:100%;">
<div class="panel-left resizable">
left panel
</div>
<div class="splitter">
</div>
<div class="panel-right" id="panelRight">
right panel
</div>
</div>
What you try do do is possible with max-width like #JHeth mentioned.
You can set the min-width to set the minimum width of your div and max-width to stop on the pixel size you want.
.panel-left {
min-width: 50px;
max-width: 200px;
width: 50%;
}
See the example below:
$(".panel-left").resizable({
handleSelector: ".splitter",
resizeHeight: false,
resizeHeightFrom:'center',
});
.panel-container {
display: flex;
flex-direction: row;
border: 1px solid silver;
overflow: hidden;
width: 100%;
}
.panel-left {
flex: 0 0 auto;
padding: 10px;
min-height: 100vh;
min-width: 50px;
max-width: 200px;
white-space: nowrap;
background: #8E44AD;
color: white;
width: 50%;
}
.panel-right {
flex: 1 0 auto;
padding: 10px;
min-height: 100vh;
background: #34495E;
color: #fff;
overflow-x: hidden;
}
.splitter {
flex: 0 0 auto;
width: 8px;
background: url(images/vsizegrip.png) center center no-repeat #ccc;
min-height: 100%;
cursor: col-resize;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.jqueryscript.net/demo/jQuery-Plugin-To-Generate-Resizable-DOM-Elements-Resizable/src/jquery-resizable.js"></script>
<div class="panel-container el" style="height:100%;">
<div class="panel-left resizable">
left panel
</div>
<div class="splitter">
</div>
<div class="panel-right" id="panelRight">
right panel
</div>
</div>
I am building a mobile application which will have a scrollable element in the middle of the screen. Currently when I try and scroll the entire app moves. I would like the all other elements to remain fixed while my element scrolls.
Here is my main React App:
class MobileServices extends Component {
render() {
return (
<div className={style.app}>
<div className={style.mobileHeader}>
<div className={style.logoBox}>
Logo Here
</div>
<div className={style.contactBox}>
</div>
</div>
<div className={style.mainContent}>
<div className={style.contentOne}></div>
<div className={style.contentTwo}></div>
<div className={style.contentThree}></div>
</div>
</div>
);
}
}
Here is the CSS:
html, body {
margin: 0;
/* height: 100% */
}
.app {
background-color: green;
background-size : cover;
background-attachment: fixed;
height: 100vh;
width: 100vw;
overflow: hidden;
}
.contactBox {
margin: 1rem;
padding: 1rem;
}
.contentOne {
background-color: blue;
display: flex;
height: 10rem;
width: 100vw
}
.contentTwo {
background-color: red;
display: flex;
height: 10rem;
width: 100vw
}
.logoBox {
border: 2px solid white;
margin: 1rem;
padding: 2rem;
}
.mainContent {
flex: 1;
display: flex;
overflow: scroll;
margin-top: 4rem;
height: 10rem;
width: 300vw;
overflow-x: auto;
}
.mobileHeader {
display: flex;
justify-content: space-between;
width: 100%;
}
I have tried making the app class fixed, but that only prevented me from being able to scroll at all.
body, html {
width: 100%;
height: 100%;
overflow: hidden;
}
.app {
// your css and
display: flex;
flex-direction: column;
}
.mainContent {
flex-grow: 1;
overflow: auto;
// rest of your css
}
Optional, you can set your mobielHeader to have position: sticky