Position: absolute behaving differently in safari - css

I am building a responsive website ( http://dev.searsdavies.co.uk/quadrant-new/ )
With a layout that requires a set of buttons to sit in the dead centre of the screen for portrait tablets, this layout is triggered at a screen width of 768px and stays in place down to 414px. The buttons are position:absolute on top of all the other content as they need to snap to the bottom on the larger and smaller versions of the site.
The boxes behave perfectly in Chrome and Firefox but safari positions them too high up the page.
Full site is above, here is the relevant CSS
.row.footer {
bottom: 49%;
transform: translate(0, 50%);
position: absolute;
padding: 0 50px;
}
.row.full-width {
width: 100%;
margin-left: auto;
margin-right: auto;
max-width: 100%;
}
There is also a conditional query that stops the layout becoming too shallow on landscape phones and similar devices:
#media screen and (max-height: 800px) and (max-width:768px) and (min-width:415px) {
.row.footer {
top:352px ;
bottom:auto ;
transform:none
}
}
.side-img {
height: 50vh;
min-height: 400px;
background-size: cover;
position: relative;
}
.main-content {
height: 50vh;
min-height: 400px;
}

A few things here.
Firstly, prefix your properties; you are using transform but you are not prefixing; they will not work in Safari.
webkit-transform: translate(x,x);
Secondly, you have this in your #media query - max-height: 800px. That means do this stuff when the browser is **less than** 800px in height - demo.
Is that really what you want to say for a #media rule targeting a portrait tablet (an iPad for example, has is 768 widthby 1024 height)?
To fix your issues:
1) prefix your transforms
2) fix your #media rules
3) remove the bottom: auto rule
4) remove/adjust the bottom: 49% rule

Related

Use multiple conditions for CSS container queries

Important - this code only works on browsers with container queries enabled
How can I use multiple conditions at the same time for container queries? Using the syntax for #media queries doesn't seem to work.
In this example, the background changes to yellow based on the width and height of the element (resize it to see). But combining the conditions to make the background blue doesn't work.
.tile {
width: 100px;
height: 100px;
border: 1px solid black;
resize: both;
overflow: auto;
container-type: size;
container-name: tile;
}
.tile__inner {
width: 100%;
height: 100%;
}
#container tile (min-width: 100px) {
#container tile (min-height: 100px) {
.tile__inner {
background: yellow;
}
}
}
#container tile (min-width: 100px) and (min-height: 100px) {
.tile__inner {
background: blue !important;
}
}
<div class="tile">
<div class="tile__inner"></div>
</div>
The combined syntax is correct in your example, and works as expected in Chrome v105 as well as Safari Technology Preview v152. I'm seeing the blue background applied when both width and height are 100px or larger.
I would guess that you are using Safari TP v151 or earlier? There was a bug in Safari TP before v152 that required parenthesis around any combination/negation syntax. I expect this will work for you either by using parenthesis (which is also valid syntax):
#container tile ((min-width: 100px) and (min-height: 100px)) {
.tile__inner {
background: blue !important;
}
}
Or by upgrading Safari to the latest TP.
codepen: https://codepen.io/miriamsuzanne/pen/dyeYoBr/30d17f519afe57c5d88f2c281dcbb5e2

Issue with max-width and the relative sizes of elements across devices

I have an issue with a media query. Using the following HTML and CSS, the b-class element is supposed to narrow to 128px when the window narrows to the point it would otherwise overlap with the a-class element (roughly). This works on my 3000x2000 laptop display, but in Firefox on my mobile in landscape mode, the elements overlap without the media query rule kicking in.
Example code: codepen.io/krainert/pen/KKzVQLPcode below
<p class="a">Here is a headline</p>
<p class="b">Here is a nav element with several menu items</p>
body, p {
margin: 0;
font-family: 'calibri';
}
.a {
font-size: 50px;
background-color: blue;
}
.b {
position: absolute;
top: 0px;
right: 0px;
font-size: 24px;
background-color: red;
}
#media only screen and (max-width: 832px) {
.b {
width: 128px;
}
}
I reckon this is caused by discrepancies between differences in device-width and the screen-relative sizes of elements across devices -- that is to say, the difference between device-width on mobile to that on my laptop is greater than the difference between the widths of the elements on mobile to those on my laptop relative to the sizes of their screens. Or maybe I'm confusing myself. What's the best way to fix it?
Try limiting the width of the .a container, so they don't overlap:
#media only screen and (max-width: 832px) {
.b {
width: 128px;
}
.a {
width: calc(100vw - 128px);
}
}

How Do I Properly Make An Image Respond To A Browser's Adjustment?

I have a simple question: How do I make an image properly respond to the viewport?
I have a 400 pixel (400px) wide and tall image, and I'd like it to become only 90% of the viewport width (90vw) when the browser is resized, so here is my current code:
img {
width: 400px;
height: 400px;
}
#media screen and (max-width: 400px) {
img {
width: 90vw;
height: 90vh;
}
}
But the problem is that the image doesn't adjust at all with this current code.
When I put max-width in place of width only the width of the image adjusts while the height does not leaving me with an elliptical and distorted image.
Is there an easy fix to my problem?
Setting both height and width in CSS for an <img> is prone to distorting it. If you don't want that to happen, you should just specify one dimension and set the other to auto. Considering your image is, in fact, 400px × 400px, here's what you should use:
#myImg {
width: 400px;
height: auto;
}
#media (max-width: 440px) {
#myImg {
width: 90vw;
}
}
/* optional, for centering */
#myImg {
display: block;
margin: 0 auto;
}
<img src="http://via.placeholder.com/400x400" id="myImg">
Play with it here. Note I used 440px so there wouldn't be a jump from 400px to 360px when crossing over the 400px device width limit. You can, of course, use 400px if that's what you want.
Try object fit.
img {
width: 400px;
height: 400px;
object-fit: cover;
}
#media screen and (max-width: 400px) {
img {
width: 90vw;
height: 90vh;
}
}
Or for better browser compatibility you can also use a background image instead.
For that you'd need to set two #media queries, one for horizontal, and one for vertical adjustment, both set to 400px. With the horizontal one, you only use the width, and with the vertical one, only the height:
body {margin: 0}
img {
display: block; /* removes bottom margin/whitespace */
}
#media (max-width: 400px) {
img {width: 90%}
}
#media (max-height: 400px) {
img {height: 90vh}
}
<img src="http://placehold.it/400x400" alt="">

Why can't i maintain aspect ratio with max height value?

I use a class for my portrait and landscape images. All my landscape images have the same size of 1400x1000px (700x500px 5K retina proof). And i want the portrait images always to be 700px in height and width set to auto, but it doesn't seem to work that way. Why?
.size-m { /* project image portrait */
max-height: 700px;
width: auto;
}
.size-xl { /* project image landscape */
max-width: 700px;
height: auto;
}
I might be misunderstanding, but this appears to be working fine in these jsfiddles:
landscape
img {
max-width: 700px;
height: auto;
}
portrait
img {
max-height: 700px;
width: auto;
}
Add display: block to your classes. That should do the trick.

Responsive design

So im self teaching myself responsive design & am trying to put together a right hand divider that remains the same size, while the left hand resizes down to 240 before pushing the right div down..
The reasoning - so that changing window sizes keeps the correct format and the design is suitable for various mobile devices (down to 240px).
Now with the way it is setup I cannot seem to get the right div to push down below the left once the screen width is reduced to less than 480px.
CSS
.menu {
position: relative;
float: left;
min-width: 240px;
margin-left: -240px;
}
.content {
position: relative;
float: left;
min-width: 240px;
}
#media screen {
.content {
width: calc(100% - 240px);
margin-right: 240px;
}
.menu {
}
}
What I can't figure out to do is to force the div (MENU) after the left div (CONTENT) for devices with a width of 480px or less? The reason for designing this way is so that the left content is scalable for all screen sizes (thus avoiding breakpoints for specific devices), but at the point where 480px is reached i want the elements to be displayed one after the other..
JS FIDDLE
After some lucky research, I have found that the following appears to work, but am not sure if this a reasonable or 'dirty' fix;
#media (min-width: 1px) and (max-width: 479px) {
.menu {
margin-left: 0px;
}
}
So a min-width and max-width is needed for the exception, in which the margin-left of <div class="menu"></div> is updated to 0px.
So below devices with a screen width of 480px it will shift the right side menu div down below the left side navigation div...
Take a look at this design.
What i've done is make it mobile first and percentage widths when your screen width is smaller than 480px the menu's take 100% of the space.
.content {
background:red;
position: relative;
width: 100%;
height: 200px;
}
.menu {
background:green;
position: relative;
width: 100%;
height: 200px;
}
This type of design is called mobile first and your should read about it on the web. It makes the styles load first on the mobile phone then progressively upgrade on wider screens.

Resources