Maintain responsive image height - javascript

I am attempting to create a CTA component at the top of my react application, that contains the navbar and the CTA text. After successfully completing the component, I am noticing a minor bug that I would like to resolve. I am only providing my image with a width of 100% and no defined height. This causes the divs beneath the image to flicker upwards until the image has fully loaded. I know not providing the image with a defined height is causing it because the bug goes away when I provide the image with a random height. I am wondering if there is a way to provide the image with a responsive height that would behave in a similar way to just providing my image with 100% width.
my css code is as follows:
body {
margin: 0;
padding: 0;
}
.container {
position: relative;
}
.container .container-background {
opacity: 0.25;
}
.container-background-img {
width: 100%;
position: relative;
}
.container .content {
position: relative;
z-index: 1;
}
.app-outer {
max-width: 1170px;
margin: 0 auto;
position: relative;
padding: 0rem 1rem;
}
#media only screen and (max-width: 1170px) {
.container-background-img {
height: 656px;
object-fit: cover;
}
}
#media only screen and (max-width: 768px) {
.container-background-img {
height: 653px;
object-fit: cover;
}
}
/* CODE ADDED */
#navbar {
position: absolute;
top: 0;
left: 0;
right: 0;
}
#content {
position: absolute;
top: 20%;
}
my jsx code is as follows:
import React from "react";
import "./styles.css";
export default function App() {
return (
<>
<div className="container">
<div className="container-background">
<img
id="rob"
src="https://i.imgur.com/iyFtMNA.jpg"
alt="bg"
className="container-background-img"
/>
</div>
<div id="content" className="content">
I am the CTA
</div>
<div id="navbar">
<div
style={{
backgroundColor: "white",
height: 100,
width: "100%",
display: "flex",
justifyContent: "center",
alignItems: "center"
}}
>
I am the navbar
</div>
</div>
</div>
<div>I am beneath the cta</div>
</>
);
}
the following link I have provided contains a code sandbox: https://codesandbox.io/s/issue-react-forked-4lsdm?file=/src/App.js:0-868
Please Note: *** within the code sandbox the issue is not very apparent, but within my react application it is much more noticeable

As you mentioned, the issue is not really clear to see from your sandbox code.
I am not sure this would fix your issue but instead of using image tag try setting your CTA component to have background-image() instead.
Make sure to add other background css attributes too such as
background-repeat: no-repeat;
background-size: cover;
background-posistion: center;
padding-bottom: 60%;
Make sure to add padding-bottom: 60% (Your image seems to have a 3:2(w:h) ratio);
Hopefully, this works for you!

Related

Can I increase the margin-top in css based on how small I make my window?

I want the space between my black div and the navbar to remain the same when I resize the window. I thought of resizing the margin-top as the window gets smaller but I do not know how to get window's current size and use it in css.
Photos:
Full sized window
Minimized window
Question.css
.Question {
background-color: #0B0C10;
margin: 2% 5% 3% 5%;
padding: 4%;
color: #C5C6C7;
}
Question.js
import React from 'react'
import './Question.css'
class Question extends React.Component {
render() {
return (
<div className='Question'>
applications of adaptive testing, starting with Binet in 1905. Adaptive tests are comprised of items
selected from a collection of items, known as an item bank. The items are chosen to match the
estimated ability level (or aptitude level, etc.) of the current test-taker. If the test-taker succeeds on
an item, a slightly more challenging item is presented next, and vice-versa.
</div>
)
}
}
export default Question;
NavBar.css
.NavBar {
background-color: #0B0C10;
position: fixed;
top: 0;
width: 100%;
border-bottom: 2px solid #C5C6C7;
color: #C5C6C7;
}
.Title {
margin-left: 5%;
}
NavBar.js
import React from 'react'
import './NavBar.css'
class NavBar extends React.Component {
render() {
return (
<div className='NavBar'>
<h3 className='Title'>CATlin</h3>
</div>
)
}
}
export default NavBar;
Thank you in advance!
.Question {
background-color: #0B0C10;
margin: 2% 5% 3% 5%;
padding: 4%;
color: #C5C6C7;
}
#media screen and (max-width: 600px) {
.Question {
margin: 4% 5% 3% 5%;
}
}
Yes, you can. "vh" is percentage of your screen height. (Also, vw: percentage of your screen width.) Please, review and run my code and resize your screen height.
.container {
margin-top: 50vh;
height: 100vh;
width: 100vw;
background-color: #ecf0f1;
}
<div class="container"></div>
If you want something more smoothly you must do this without media queries using only vw and vh units.
.foo {
margin-top: 10vw; /* the margin top will be 10% of window width */
}
.bar {
margin-top: 10vh; /* the margin top will be 10% of window height */
}

Stop div overlapping another from size increase

My engagement-filtercontainer div used to sit directly above my engagement-graphcontainer unless it was expanded via button click, in which case it drops down into the graphcontainer overlapping. Now the engagement-filtercontainer has grown in size because of additional content and it overlaps my graph container which contained my svg. I need it to dynamically not do this even if my filter increases in size.
I have some divs that are contained in this order:
<div class="Engagement-Container">
<div class="Engagement-Body">
<div class="Engagement-Graph" id="graph">
<div class="Engagement-FilterContainer"
</div>
<div class="Engagement-GraphContainer"
<svg
class="Engagement-GraphSVG"
xmlns="http://www.w3.org/2000/svg"
version="1.1 ">
</svg>
</div>
</div>
</div>
</div>
Notice that the engagement-filtercontainer and graphcontainer are both within the engagement-graph div, and that my svg is contained within the graphcontainer.
In the below image you can see that the filter now with more content expands into the area (I have hidden with css thats why im showing it in dev mode, ive tried various methods to work around this but I think i need a definitive solution.
The CSS:
engagement-graph(parent div)
.Engagement-Graph {
position: absolute;
width: 100%;
height: 100%;
font-size: 100%;
vertical-align: baseline;
overflow: hidden;
#include tablet() {
width: 65%;
}
}
Engagement-graph-container (contains the svg graph that i want to protect from unwanted overlap)
.Engagement-GraphContainer {
position: relative;
width: 100%;
height: calc(100% - 56px);
top: 0;
background-color: $gray-bg-color;
transition: height $filter-slide-duration, top $filter-slide-duration;
#include tablet() {
background-color: white;
height: 100%;
}
svg {
width: 100%;
height: 100%;
}
&--WithFilter {
height: calc(100% - 480px) !important;
top: 480px !important;
#include landscape {
height: calc(100% - 436px) !important;
top: 436px !important;
}
}
}
Filter-container (that is overlapping)
.Engagement-FilterContainer {
overflow: overlay;
display: table;
position: absolute;
width: 100%;
z-index: 10;
transition: transform $filter-slide-duration;
transform: translateY(-486px);
visibility: hidden;
&--Visible {
transform: translateY(0) !important;
}
#include landscape {
transform: translateY(-436px);
}
}
I wish for the filter to work as usual so when its expanded it will appear into the screen but when it is not, I don't want it encroaching upon the graph, no matter how large it gets. When the filter was smaller it was fine it never came into the screen, so it must not be dynamic in how it is sized.
Thank you if you can help.

React responsive carousel height not adjusting properly

I am using react responsive carousel and it's rendering weird
render() {
return (
<div className="slider-container">
<Carousel className="carousel-style" showArrows={true} showThumbs={false} showStatus={false}>
{this.generateCards()}
<div className="slider-item-div">
Test
</div>
</Carousel>
</div>
);
}
Here's the CSS
.slider-container {
width: 100%;
height: 100%;
}
.slider-item-div {
padding: 20px;
background-color: white;
text-align: center;
height: 100%;
width: 100%;
}
.carousel-style {
height: 100% !important;
}
and unfortunately this is what it renders as
I would like to have the height == 100% and fill the screen. Also I'd like the right and left arrows to be show without hovering over them like here:
http://react-responsive-carousel.js.org/#demos
If you're wanting this carousel to fill the screen, then the following CSS adjustments should achieve that:
.slider-container {
width: 100%;
height: 100%;
/* Add this */
position:fixed;
top:0;
left:0;
}
this might actually be a bug, because when I change the height pixel wise, it does adjust but if I do percentage for it to match parent it doesn't do anything
Make changes in CSS and fixed position of the slider container
.slider-container {
width: 100%;
height: 100%;
position:fixed; /* add this code for position fixed */
top:0px; /* set top and left 0 */
left:0px;
}
.slider-item-div {
padding: 20px;
background-color: white;
text-align: center;
height: 100%;
width: 100%;
}
.carousel-style {
height: 100% !important;
}
If you're not against the idea of overriding the default CSS styling, then you could create a CSS file with the following:
.carousel .thumb img {
width: 100% !important;
height: 100% !important;
}
.carousel .slide img {
max-height: 300px; /* change this to whatever you want */
width: auto;
}
and then in your code (assuming ES6 syntax) you would simply override the defaults by importing the CSS file you created. For example:
import React, { Component } from 'react';
import { Carousel } from 'react-responsive-carousel';
import 'react-responsive-carousel/lib/styles/carousel.min.css';
import './style/overrides.css'; // change this to the file path of your overrides

Fixed aspect ratio box with letter and pillarboxing between header and footer

Running the following code snippet will provide a framework for what I am visually hoping to accomplish, with some concessions made in the CSS that I'd like to remove:
body {
height: 100vh;
margin: 0;
}
.container>* {
height: 100%;
width: 100%;
flex: 0 0 50px;
}
.container {
width: 100%;
height: 100%;
background-color: black;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.header {
background-color: red;
}
.content {
background-color: blue;
flex: 1;
position: relative;
}
.footer {
margin-top: auto;
background-color: yellow;
}
.fixedRatio {
height: 56.25vw;
max-height: calc(100vh - 100px);
width: calc((100vh - 100px) * (1/0.5625));
;
max-width: 100vw;
background-color: rgba(0, 0, 0, 0.5);
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
<div class="container">
<div class="header"></div>
<div class="content">
<div class="fixedRatio"></div>
</div>
<div class="footer"></div>
</div>
Included are a header and footer of arbitrary height and a fixed aspect ratio box centered vertically and horizontally between them. I'd like it to letter- and pillar-box as the page is resized, and respond to increases/decreases in header height.
As it stands, the code accomplishes many of these goals but falls short in that it requires that the heights of the header and footer be included in the CSS for the fixed aspect ratio box. This limits my ability to freely manipulate the size of the header, or let it grow arbitrarily as a function of content (at least to the extent I am not using JavaScript).
I've managed to make this work successfully for the case of letter-boxing (top and bottom black bars) by leveraging the fact that the content is full-width. As a result, I can use 100vw / 56.25vw (in the case of 16:9) for the width/height and achieve the desired result. Unfortunately, when moving the content around to pillar-box, this obviously falls apart.
I've more or less resigned myself to needing JavaScript to - at the very least - toggle a class based on the dimensions of the inner content box to determine whether letter or pillar boxing is appropriate. However, it became very clear very quickly that setting width as a function of height is not trivial.
I was fortunate to come across this post, where a solution leveraging a 1x1 pixel is used to set width as a function of height.
I was able to successfully make this work for the pillar-boxing case in both Chrome and Safari, but not Firefox (IE11 and Edge not yet tested, but coverage is desired... pray for me). I'd like to get recent versions of Chrome/Safari/Firefox covered, as well as I11/Edge if possible.
The solution for Chrome/Safari is as follows:
body {
height: 100vh;
margin: 0;
}
.header,
.footer {
height: 100%;
width: 100%;
}
.container>* {
flex: 0 0 50px;
}
.container {
width: 100%;
height: 100%;
background-color: black;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.header {
background-color: red;
}
img {
display: block;
height: 100%;
background: orange;
}
.content {
background-color: blue;
flex: 1;
position: relative;
overflow: hidden;
height: 100%;
display: inline-block;
left: 50%;
transform: translateX(-50%);
}
.footer {
margin-top: auto;
background-color: yellow;
}
.fixedRatio {
background-color: purple;
position: absolute;
left: 0;
top: 0;
right: 0;
margin: auto;
bottom: 0;
}
<div class="container">
<div class="header"></div>
<div class="content">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" />
<div class="fixedRatio"></div>
</div>
<div class="footer"></div>
</div>
There are a few things to consider. I am comfortable with fixing the height of the footer. This constraint may prove valuable, but I've been unable to yield anything from it yet. I am also comfortable with radical alterations to the included markup, supposing it enables the desired behavior.
The end-purpose of this would be to maintain fixed aspect ratio content between this flexible header, static footer, and overlay content upon it.
I am well aware that I could run some JavaScript and set these heights manually with great success, but I am coming at this from a position largely based in intellectual curiosity. If you, too, are curious, perhaps you can lend a hand in exploring :)
Thank you!

Problems with window resize using vw and vh measures

Im experimenting with vh and vw measures so I have stuck with this problem: when I resize window vertically/open chrome console and then scroll window down background doesn't load in a process of scrolling. How I can recalculate window view ? Or how else I can fix this problem? Is it necessary to use media queries?
Any help will be appreciate.
.m-page-header {
display: flex;
}
.m-page-header__wrapper {
margin: 0 auto;
}
.m-page-header__img-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
}
.m-page-header img {
max-width: 100%;
height: auto;
display: block;
}
.main-content {
display: block;
background-image: url("https://image.ibb.co/hTboSm/1_HEADER_bg.jpg");
background-size: 100%;
background-repeat: no-repeat;
width: 100vw;
height: 100vh;
}
.main-content__wrapper {
max-width: 960px;
margin: 0 auto;
}
html,
body {
height: 100%;
}
body {
min-width: 960px;
}
.visually-hidden {
display: none;
}
<body>
<main class="main-content">
<div class="main-content__wrapper">
<header class="m-page-header">
<div class="m-page-header__wrapper">
<section class="m-page-header__img-container">
<h2 class="page-header__header-text visually-hidden">Game</h2>
<img src="https://image.ibb.co/cNjQ7m/1_HEADER_logo.png" alt="Game">
</section>
</div>
</header>
</div>
</main>
</body>
You have two solutions :
1) add background-size: contain to .main-content :
window resizing will not crop the background anymore. The background will stay completely visible but it won't stretch horizontally.
https://jsfiddle.net/o0p9y03f/
2) add background-size: cover to .main-content :
The background will keep on stretch horizontally but it will be cropped to fill the entire container.
In any case you will have to deal with the size and the centering of the container, depending on which result you are looking for.
https://jsfiddle.net/o0p9y03f/1/

Categories