I was on the console viewing a site I was working on and noticed my banners looked off.
<div class="blog-post-featured-banner">
<img width="1600" height="900" src="#">
</div>
.blog-post-featured-banner {
height: 50vh;
overflow: hidden;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.blog-post-featured-banner img {
width: 100%;
height: auto;
}
It looks fine on desktop, but when I view it on my PS4 it looks like the img had height:100%;, it looked squished. I expected it to behave the way it does on desktop, it takes 100% width of the screen and the height is hidden in the overflow. Given I'm viewing it on a TV I expected it to get a bit pixelated. Could it just be needing a very large image? The TV is 55".
Sort of a side question, but in the div that holds the image, I was trying to make the image vertically and horizontally centered in the "frame", how could I adjust my css to do so, if possible.
The browser that Playstation use might not support viewport units. The viewport units are gaining support on all modern browsers, however, there are some cases where this unit is not supported or bugs have been found.
Try setting the html and body tag's height to 100%. Then set your "blog-post-featured-banner" height to 50%. This should replicate what you are trying to achieve currently.
<div class="blog-post-featured-banner">
<img width="1600" height="900" src="#">
</div>
html, body {
height: 100%
}
.blog-post-featured-banner {
height: 50%;
overflow: hidden;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
.blog-post-featured-banner img {
width: 100%;
height: auto;
}
I had a friend look at this. My side question sort of led to the answer, not saying what you guys answered was incorrect, but this did what I wanted.
<div class="blog-post-featured-banner">
<div class="featured-banner" style="background: url(<?php the_post_thumbnail_url( 'full' ); ?> ) no-repeat center center; background-size: cover;">
</div>
.blog-post-featured-banner {
height: 50vh;
overflow: hidden;
position: relative;
}
.featured-banner {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
The 50vh seemed to work on the PS4's browser.
Related
For the desktop landing page, I want this composition of images to maintain it's height in relation to the browser height (75vh), otherwise this landing collage will become too horizontal/skinny as someone shrinks the width of their browser.
As it changes proportion with the page getting wider or narrower, I want the images inside to be cropped, not stretched.
I figured out a way to crop them, but only if I set an actual px height to the images. I don't want that. I want the height to be in proportion to the browser height. If I make the divs they're in a ratio of the height of the browser, then the images just stretch inside to fit the div.
<div class="landing">
<div class="landing-side"><img src="landing-1.jpg" alt=""></div>
<div class="landing-side"><img src="landing-2.jpg" alt=""></div>
<div class="landing-center"><img src="landing-3.jpg" alt=""></div>
<div class="landing-side"><img src="landing-4.jpg" alt=""></div>
<div class="landing-side"><img src="landing-5.jpg" alt=""></div>
</div>
.landing {
position: relative;
width: 100%;
height: auto;
display: flex;
}
.landing img {
width: 100%;
height: auto;
display: block;
}
.landing-center,
.landing-side {
height: 75vh;
display: flex;
flex: 1 1 auto;
overflow: hidden;
justify-content: center;
}
.landing-center {width: 40%;}
.landing-side {width: 15%;}
Here is how I did it before - at a certain browser width, the height would be fixed in px, then the side images would start getting cropped*. This is OK, but then I'd have to do make it hop to various specific image heights at different widths. Whereas I want the height of the whole larger container of images to change as the browser changes proportions.
.landing {
position: relative;
width: 100%;
display: flex;
}
.landing img {
width: 100%;
height: auto;
display: block;
}
.landing-center,
.landing-side {
display: flex;
flex: 1 1 auto;
overflow: hidden;
justify-content: center;
}
#media screen and (max-width: 1536px) {
.landing-center {flex-shrink: 0;}
.landing-center img,
.landing-side img {
width: auto;
height: 400px;
}
}
*(Note: I'd prefer that only the side images get cropped in the first code example as well, but that may complicate things too much for this one question.)
To croping an image, you need to use overflow: hidden;
just like:
.croped-content {
position: relative;
width: 25vw;
height: 70vw;
border: 2px solid red;
overflow: hidden;
}
.croped-content img {
min-width: 100%;
min-height: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="croped-content">
<img src="https://cdn.pixabay.com/photo/2017/10/06/07/29/guava-2822182_1280.png" alt="guava">
</div>
All I had to do is put the vh here, instead of the px. This works now. I got all mixed up trying too many ways to make this work that I missed the fact that I had put the height attribute to the container instead of the image.
.landing-center {flex-shrink: 0;}
.landing-center img,
.landing-side img {
width: auto;
**height: 75vh;**
}
Hope you are well,
The following image highlights my CSS problem. The white bordered div with 'Contact' in the middle, I want to stick to the bottom of the screen.
Here is the CSS applied to that div as well as it's wrapper div! Note. I'm having this problem after the media queries are applied.
<div className='wrapperLanding'>
<div className="contentWrapper">
<p className="content">Illumination AI is a start-up studio that is focused on applying AI and ML to novel combinations of data across a diverse range of industries.</p>
<a className="contact" href="mailto:info#illumination.ai?subject=illumination20%AI%20Site%20Contact%20Inquiry">Contact</a>
</div>
</div>
/* contentWrapper is the child of wrapperLanding */
.wrapperLanding{
background-image: url("../images/lighthouseBackdrop.jpg");
height: 100vh;
background-size: cover;
background-position: center;
display: flex;
align-items: center;
flex-direction: column;
}
.contentWrapper{
position: absolute;
bottom: 3%;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
#media (max-height: 700px) {
html,
body{
overflow-y: visible;
}
.wrapperLanding{
height: 700px;
}
.contentWrapper{
/* position: fixed; */
bottom: 3%;
}
}
You may have noticed I have 'position: fixed;' commented out. With it applied, it still doesn't quite deliver the desired effect, as demonstrated below.
The problem here, is that while the image is stuck to the bottom of the user's view... it is NOT stuck to the bottom of the wrapping div! Any suggestions?
Thanks for your time!
I want to use a simple layout, that consists of
An image
Some text
The text should be on the bottom and all remaining space should be used by the image. It seemed a simple task, but it has been a frustrating journey. Finally, I nailed but this solution doesn't work on mobile devices (Android and/or Chrome).
JSFiddle here
It looks like this on the desktop:
Unfortunately, the iPad renders it like this:
The text is barely visible, because the image took all the space. On Android (with Chrome 65 installed) it shows some of the text, but not all of it.
I use the following HTML code
<html>
<body>
<h1>TEST 123</h1>
<div class="wrapper img-top">
<img class="image" src="..." />
<div class="text">
<h2>Header</h2>
<p>...</p>
</div>
</div>
</body>
</html>
The relevant parts of the CSS looks like this (full code on JSFiddle):
* {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
height: 100vh;
overflow: hidden;
}
.wrapper {
display: grid;
grid-gap: 10px;
height: calc(100vh - 85px);
margin-bottom: 20px;
text-align: center;
align-items: center;
}
.wrapper.img-top {
grid-template-rows: 1fr auto;
}
.wrapper.img-top .image {
grid-row: 1;
justify-self: center;
}
.wrapper.img-top .text {
grid-row: 2;
justify-self: center;
}
.wrapper img.image {
max-height: 100%;
max-width: 100%;
}
I guess that there is a problem with the automatic image sizing, but I don't know what to do next? I want to have it responsive, but it just is not going to work.
Your problem is that you put fixed height on img-top. Your img is, let's say, 900 px, it's not the same on screen as iPad and desktop. Since you put your image to be 1 fr of height, it is getting bigger as screen is getting smaller. So you have two solutions, as far as I can tell, first is to restrict the size of your image, max-height: 300px;, or try putting overflow auto on .img-top.
Thanks #Jakub Muda for the suggestion about using flexboxes. I have finally fixed the problem by moving to a flexbox and fix the remaining issues.
After switching to a flexbox, I kept the same problem. The image was sized to 100% of the size of the parent wrapper div. I have fixed this by adding overflow: hidden to the image, so it will not overflow. This worked fine, but some images were distorted, because the aspect-ratio wasn't properly maintained. Adding object-fit: contain fixed this issue.
The complete sample can be found at JSFiddle, but for completeness I have added the CSS here as well:
* {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
height: 100vh;
overflow: hidden;
}
.wrapper {
display: flex;
flex-direction: column;
height: calc(100vh - 85px);
margin-bottom: 20px;
text-align: center;
align-items: center;
}
.wrapper .image {
justify-self: center;
flex: auto;
overflow: hidden; /* Important to make sure the image stays within bounds */
object-fit: contain; /* Important to make sure the image keeps its aspect ratio */
}
.wrapper .text {
justify-self: center;
flex-basis: none;
padding-top: 10px;
}
.wrapper img.image {
max-height: 100%;
max-width: 100%;
}
I have a div called .side-el which I would like to have in a position: fixed; behavior, but as soon as I apply position fixed the width alternates from the right one. The right width would be the one set by flexbox. How can I achieve this goal?
.container {
-webkit-align-content: flex-start;
align-content: flex-start;
-webkit-align-items: flex-start;
align-items: flex-start;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-justify-content: flex-start;
justify-content: flex-start;
* {
box-sizing: border-box;
-webkit-flex-grow: 1;
flex-grow: 1;
-webkit-flex-shrink: 0;
flex-shrink: 0;
}
}
.main-el {
box-sizing: border-box;
padding:0 2em;
width: 70%;
}
.side-el {
box-sizing: border-box;
width: 30%;
}
<div class="container" style="background-color: blue; height: 100px;">
<div class="main-el">
<div style="background-color: red; height: 1000px;">content</div>
</div>
<div class="side-el" >
<div style="background-color: red; height: 100px;">content</div>
</div>
</div>
Here's a way to do this inspired by bootstrap:
.fixed-top {
display: flex;
position: fixed;
top: 0;
left: 0;
right: 0;
}
This gives your flex-box room to breathe and do it's flex-box thing. If your flex-direction is column, you could use top, left, bottom instead.
This works because when you give an element a fixed position and a left and right of 0 or a top and bottom of 0, the element is stretched to fill the space from left to right, or top to bottom. That in turn allows a flex-box to use the amount of space you would expect without position fixed.
You can't.
As explained by the CSS2.1 spec:
Absolutely positioned boxes are taken out of the normal flow.
And the Flexible Box Layout spec confirms that:
An absolutely-positioned child of a flex container does not
participate in flex layout. However, it does participate in the
reordering step (see order), which has an effect in their
painting order.
(Emphasis mine)
#Daniel , I know this is very late but ... while the accepted answer is correct, I don't feel it's very helpful.
I had the same question (which is how I came across this post), and the solution I think I'll go with is to wrap the position fixed element within the flex element.
Here's a (very ugly) example
Relevant Markup
<aside class="Layout-aside" ng-class="{'isCollapsed': collapsed}" ng-controller="AsideCtrl">
<div class="Layout-aside-inner">
<button ng-click="collapsed = !collapsed">
<span ng-show="collapsed">></span>
<span ng-hide="collapsed"><</span>
</button>
<ul class="Layout-aside-content">
<li ng-repeat="i in items">{{i}}</li>
</ul>
</div>
</aside>
Relevant CSS
.Layout-aside {
order: 0;
min-width: 140px;
width: 140px;
background-color: rgba(0, 255, 0, .4);
transition: width .4s, min-width .4s;
}
.Layout-aside.isCollapsed {
min-width: 25px;
width: 25px;
}
.Layout-aside-inner {
position: fixed;
}
.Layout-aside.isCollapsed .Layout-aside-inner {
width: 25px;
}
.Layout-aside.isCollapsed .Layout-aside-content {
opacity: 0;
}
position:sticky was mentioned by Juozas Rastenis above but without code example.
Here's a minimalist example:
* {
box-sizing: border-box;
}
body {
display: flex;
margin: 0;
}
nav {
width: 20%;
height: 100vh;
top: 0; /* this is required for "sticky" to work */
position: sticky;
background: lightblue;
padding: 1rem;
}
main {
height: 3000px; /* cause scroll */
background: lightpink;
flex-grow: 1;
padding: 1rem;
}
<body>
<nav>
sidebar here
</nav>
<main>
content here
</main>
</body>
You can achieve it with a css alternative position: sticky
It acts great but the only problem is browser support (June 2018):
https://caniuse.com/#feat=css-sticky
Hope it gets better soon.
A far simpler solution would be to use overflow-y:scroll and height: 100vh on the main-el container. This will give the appearance of fixed position to the side-el container without resorting to position: fixed.
You are saying you want position:fixed;-like behavior that plays together with flexbox. As mentioned in the accepted answer, applying this property to an element drops it out of the normal flow, so this isn't really possible.
If what you want is to have a fixed sidebar .side-el and a scrollable content box .main-el as the items of a flex container, here's how you might do this:
Disable scrolling in the flex container's parent; let's assume it's
<body>, as you don't provide div.container's parent. Also, hard-set
it's height to viewport-height (100vh) so that no part of the body's
box remains outside view (imagine the body's box normally extending
beyond your screen to contain the entire document; you don't want
that, if you are to disable the ability to move the viewport via
scrolling).
Set the flex container's (.container) height to that of it's parent.
Selectively re-enable scrolling for the content box (.main-el).
In CSS:
body{
overflow: hidden;
height: 100vh;
}
.container {
display: flex;
height: 100%;
}
.main-el {
overflow-y: auto;
}
You can achieve this without position: fixed; by just adding overflow: auto; and height: 100%; to the flex-item that contains the long content:
.container {
display: flex;
}
.main-el {
padding:0 2em;
width: 70%;
overflow: auto;
height: 100%;
}
.side-el {
width: 30%;
}
<div class="container" style="background-color: blue; height: 300px;">
<div class="main-el">
<div style="background-color: red; height: 1000px;">content</div>
</div>
<div class="side-el" >
<div style="background-color: red; height: 100px;">content</div>
</div>
</div>
I had the same issue, I actually just found a way to have flex-box, a width for the nav bar, and center it while in a fixed position.
nav {
display: flex;
height: 50px;
width: 90%;
left: 5%;
position: fixed;
}
I wanted to be able to have a flex-box nav bar in a fixed position but centered. So what I did was do the left 5% since that's equal to half of the 10% width left over. Try it out, it might help you! :)
I have a div container where I want to put in a centered image and a small description to the right. The specifications are:
The image should have a bottom margin of 35px.
The image should always show fully on the screen, so it resizes when the screen does. It should have the biggest size possible, but never be cropped and never use scrollbars.
The image should be centered with respect to the container, with the text showing on the right margin.
The text should be left-aligned horizontally, center-aligned vertically and have a 30px separation from the image.
I've tried using a table in the container and using divs, but I can't find a clean solution. I can show you the non-working code I've tried on request.
This one was a tricky one. The actual tags used don't really matter, just the number of elements and how they are nested.
The vertical centering of the text is done via Flexbox, which has limited support (Chrome, IE10, Opera, Safari, most mobile browsers). Firefox (with 2009 Flexbox properties) would normally be lumped in here, but it has a bug that prevents Flexbox from working if it is applied to an absolutely positioned element.
http://cssdeck.com/labs/iu0gx2wk
Markup:
<div class="gallery">
<article>
<h1>My image title</h1>
<img src="http://placekitten.com/640/480" alt="A really cute kitten" />
</article>
</div>
CSS:
.gallery {
padding: 0 230px;
text-align: center;
}
article {
display: inline-block;
max-width: 100%;
position: relative;
}
img {
max-width: 100%;
vertical-align: text-bottom;
}
h1 {
position: absolute;
text-align: left;
right: -230px;
top: 0;
bottom: 0;
width: 200px;
margin: 0;
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
Alternately, you could add one extra element and use the table/table-cell display properties to get your vertical centering.
http://cssdeck.com/labs/lqgjgghw
Markup
<div class="gallery">
<article>
<h1><span>My image title</span></h1>
<img src="http://placekitten.com/640/480" alt="A really cute kitten" />
</article>
</div>
CSS
.gallery {
padding: 0 230px;
text-align: center;
}
article {
display: inline-block;
max-width: 100%;
position: relative;
}
img {
max-width: 100%;
vertical-align: text-bottom;
}
h1 {
position: absolute;
text-align: left;
right: -230px;
top: 0;
bottom: 0;
width: 200px;
margin: 0;
display: table;
}
h1 span {
display: table-cell;
vertical-align: middle;
}
* note that the demos have their padding/positioning off by a little bit, the code listed here is correct.