Problem With #Media rules. Trying to Display Well in Mobile - javascript

I'm trying to get a site to display well in mobile as well as desktop but there is one part of the site that doesn't render well it's good in desktop but when I switch to mobile:
Mobile
Desktop
I've been playing around with different media queries to no avail. Adjusting the scale does nothing Here is the code. Thanks in advance to any who help.
const date = new Date();
var minutesNow= date.getMinutes();
var remainder = minutesNow%15;
var minutesLeft = 15-remainder;
var secondsNow = date.getSeconds();
let time = (86400 -(3600*24 - 60*minutesLeft + secondsNow));
var clock = $('.clock').FlipClock(time, {
countdown: true
});
#clock1 {
display: inline-block;
width: auto;
}
.container {
text-align: center;
}
#media only screen and (max-width: 600px) {
#clock1 {
transform: scale(0.8)
}
}
<br>
<link href="https://api.chipware.co.za/css/flipclock.css"rel="stylesheet" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://api.chipware.co.za/js/flipclock-min.js"></script>
<div class="container">
<div class="clock" id="clock1"></div>
</div>

Assuming you are doing Desktop first approach:
Use 'flex' box instead of 'inline-block' on the parent
.container{
display: flex;
flex-wrap: wrap
justify-content: middle;
aligh-items: center;
flex-direction: row;
}
And for using media query just, change the direction to vertical:
.container{
flex-direction: column;
}
If on mobile you want one part of the clock per line, just adjust the margin of the child element on smaller screens to make each part use width of the screen.
Also, try and use, width on each child element and 'flex-grow' property to get a better understanding.
https://www.w3schools.com/cssref/css3_pr_flex-grow.asp

Related

Transition on multiple elements at the same time using JavaScript

Cheers! I'm having an issue debugging certain behavior that occurs mostly in the Chrome browser. Here is the simplified example: https://jsfiddle.net/pd3xb2uo/
The objective is to transition multiple elements via JS code at the same time. In the example when you click on the button, items are moved to the left using translate3d added via JS. It works fine, but there are some caveats:
There is a small gap appearing between the items most of the time
Sometimes when you click faster on the button there is a large gap appearing between the items.
Here are the screenshots of both cases:
Any help or ideas on why it is happening would be highly appreciated:) It looks like there is a few milliseconds delay before the style attribute is updated on certain elements, but I have no idea why:/
The problem occurs because you are transitioning 100 elements at the same time and because of half-pixel transitions.
If you know how wide and how many elements you have, then you can do it like so:
const container = document.querySelector('.container-inner');
for (let i = 1; i < 100; i++) {
const div = document.createElement('div');
div.classList.add('element');
div.textContent = `Element ${i}`;
container.appendChild(div);
}
let transition = 0;
document.querySelector('button').addEventListener('click', () => {
transition -= 100;
container.style.transform = `translateX(${transition}px)`;
});
.container{
width: 100%;
overflow: hidden;
}
.container-inner{
display: flex;
flex-direction: row;
transition: transform .3s;
}
.element {
width: 100px;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
padding: 2rem;
text-align: center;
transition: transform .3s;
background-color: #A67583;
}
<button>Move</button>
<div class="container">
<div class="container-inner"></div>
</div>
Now only one element gets transitioned and it is working smoothly.

Dynamically flexible width & number items with flex

I have a set of tags, that I want to show in the client. However, sometimes you might have too many tags and you want to show only one row of tags maximized to your body's width without setting a fixed number of columns or item width, and adding a show more button at the end of the tag list with the same style as a tag.
I have achieved this using Javascript in my Angular project by doing the following:
Find out the width of your tags container dynamically, with ViewChild on my content container:
let contentWidth = this.contentContainer.nativeElement.clientWidth;
Calculate the text width of the see more button and use it to calculate the new content width minus see more button width:
Calculating text function does the following:
const canvas = document.createElement('canvas'); // create a canvas
const context = canvas.getContext('2d'); // get the context
context.font = '12px avertastd-bold'; // set up your font and size
And calculate the text width:
const seeMoreButtonWidth = context.measureText(seeMoreButtonText).width;
Create a new array variable 'previewTags' which will hold the tags that are visible when the tags body is in collapsed state, and fill in as many tags as you can by calculating each tag's width with it's content text you receive from the API by checking if the next tag + its padding (static value) fits into the width.
(Not runnable here)
for (const tag of this.data.tags) {
const width = context.measureText(tag).width;
if (contentWidth - (width + this.tagsPadding) > 0) {
previewTags.push({text: tag});
contentWidth -= (width + this.tagsPadding);
} else {
break;
}
}
Push the see more button at the end of previewTags list:
previewTags.push({text: seeMoreButtonText, isButton: true});
And it looks like this in the html:
<ng-container *ngFor="let tag of previewTags">
<div class="tag" [ngClass]="{'see-more-button': tag.isButton}">{{tag.text}}</div>
</ng-container>
Output:
Resize:
As you see, now the tags are flexiable (this code does not include the show more functionality).
After giving you this background and understanding of what I am doing, I would love to ask if this is possible to achieve with css or less JavaScript intervation?
Something like this could be a pure css solution if your tags have a constant height. I just let the flex-list wrap around and then don't show the overlap.
.content_wrapper {
display: flex;
justify-content: flex-start;
flex-direction: rows;
}
.tag_wrapper {
display: flex;
justify-content: flex-start;
flex-direction: rows;
flex-wrap: wrap;
width: 80%;
height: 32px;
overflow: hidden;
}
.tag_wrapper div {
width:100px;
height:30px;
border: 1px solid black;
}
button {
flex-grow: 4;
}
<div class="content_wrapper">
<div class=tag_wrapper>
<div>Tag1</div>
<div>Tag2</div>
<div>Tag3</div>
<div>Tag4</div>
<div>Tag5</div>
<div>Tag6</div>
<div>Tag7</div>
<div>Tag8</div>
<div>Tag9</div>
</div>
<button>See more</button>
You could probably make the "See more" button solution more elegant, to not have as much white space but I'll leave that to you :)
Here is some javascript to remove the see-more button if it's not needed.
(OBS) this only works if all the tags are the exact same width and have the same margin. I did this to avoid looping through all values and checking their width individually.
(I know the list is in the wrong order, I made it like that to get the see-more button fit in well without having to tinker a bunch.
function getWidthWithMargin(elem) {
var style = elem.currentStyle || window.getComputedStyle(elem)
margin = parseFloat(style.marginLeft) + parseFloat(style.marginRight)
return(elem.getBoundingClientRect().width + margin)
}
function handleWindowSizeChange() {
let tags = document.getElementsByClassName("tag");
if(tags.length != 0)
{
let tag_width = getWidthWithMargin(tags[0]);
if(tags[0].parentElement.getBoundingClientRect().width/tag_width > tags.length) {
document.getElementById("see-more-button").style.display = "none";
}
else{
document.getElementById("see-more-button").style.display = "block";
}
}
}
window.onload = handleWindowSizeChange;
window.onresize = handleWindowSizeChange;
.content_wrapper {
}
.tag_wrapper {
display: flex;
justify-content: flex-start;
flex-direction: row-reverse;
flex-wrap: wrap;
width: 100%;
height: 32px;
overflow: hidden;
}
.tag_wrapper div {
min-width:100px;
height:30px;
border: 1px solid black;
margin: 10px;
}
.tag_wrapper button {
height:30px;
flex-grow: 50;
}
<div class="content_wrapper">
<div class=tag_wrapper>
<button id="see-more-button">See more</button>
<div class="tag">Tag1</div>
<div class="tag">Tag2</div>
<div class="tag">Tag3</div>
<div class="tag">Tag4</div>
<div class="tag">Tag5</div>
<div class="tag">Tag6</div>
<div class="tag">Tag7</div>
<div class="tag">Tag8</div>
</div>

CSS display:grid overflow issue

I am creating a simple web app using angularjs for managing some kind of tickets. Tickets should be displayed in grid (.ticket-container). I am using CSS display: grid and rows and columns are dynamically set based on config file. Setting of the grid columns and rows is done using this code:
vm.getGridStyleDefinition = function () {
return {
"grid-template-rows": "repeat(" + vm.numberOfRows + ", 1fr)",
"grid-template-columns": "repeat(" + vm.numberOfColumns + ", 1fr)"
}
};
The simplified structure of the page is:
HTML
<div class="container">
<div class="flex1">
<div class="ticket-container">
<ticket></ticket>
<ticket></ticket>
<ticket></ticket>
...
</div>
</div>
<div class="menu-bar"></div>
</div>
CSS
.container {
height: 100vh;
display: flex;
flex-direction: column;
}
.flex1 {
flex: 1;
align-items: stretch;
display: flex;
}
.ticket-container {
display: grid;
width: 100vw;
grid-template-rows: repeat(5,1fr); // dynamically set
grid-template-columns: repeat(3,1fr); // dynamically set
padding: 1vh;
grid-gap: 1%;
}
.menu-bar {
background-color: blue;
}
My problem is that fractions in grid (1fr), for rows, are not calculated based on the container height, but reather on the content inside the cells. I want to force the content inside the cells to take the space that is available and not to overflow, or to force the grid to squeeze the content.
Here is codepen for this issue: link
If there is another approach to create grid that its cells will not overflow, please suggest.
Thanks in advance

Get screen size to choose matching header picture

Hej,
I had a JavaScript solution for checking the screen size and choosing a matching picture. But I lost this unfortunately.
My Problem: I want to choose a header picture (CSS responsive not possible) regarding to the screen size. Visitor with 1920x1080 will see a picture matching to this size. For usual sizes I will build special header pictures.
When Visitor has JavaScript disabled he should see a standard picture.
Mobile device has it´s own header.
Can anyone please help out…Thanks :)
Best Regards
Madeleine
You have a lot of ways to check the screen size:
If you are using jQuery you can use the screen object in the following way:
screen.width;
You can also get the size of the window or the document using:
$(window).width(); // returns width of browser viewport
$(document).width(); // returns width of HTML document
Here is a cross browser solution with pure JavaScript:
var width = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
Regarding responsive images without using Media Querys, Flexbox is a great Solution:
body { margin: 0; background: #333; }
header {
padding: .5vw;
font-size: 0;
display: -ms-flexbox;
-ms-flex-wrap: wrap;
-ms-flex-direction: column;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
display: -webkit-box;
display: flex;
}
header div {
-webkit-box-flex: auto;
-ms-flex: auto;
flex: auto;
width: 200px;
margin: .5vw;
}
header div img {
width: 100%;
height: auto;
}
<header>
<div><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/jeremiah-wilson-1.jpg" alt></div>
<div><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/jeremiah-wilson-2.jpg" alt></div>
<div><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/jeremiah-wilson-3.jpg" alt></div>
<div><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/jeremiah-wilson-4.jpg" alt></div>
<div><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/jeremiah-wilson-5.jpg" alt></div>
</header>
Resize this Codepen to see a Flexbox Responsive Header
If you header image is set as a background image you can set:
background-size: contain
background-size: cover
Hope this can help you.
If you are Using jQuery, you can check the Screen size (when the document structure is ready) and display acoordingly your wanted image:
$(document).ready(function() {
if ($(window).width() < 960) {
$('selector').css({'background-image':'url(images/small-
image.jpg)'});
}
else {
$('selector').css({'background-image':'url(images/big-image.jpg)'});
}
});

Navigation transition

I am new to jQuery and am teaching myself as I go but am struggling to figure out how to indicate that on up scroll the white navigation background moves up to show the white navigation text on panel 1?
bartaile.com is what I am using as inspiration & the changes I'm making to bartaile's navigation are---> after the user scrolls past the first panel the navigation hides, only when the user scrolls up does the navigation show again, when panel 1 comes back down the white navigation backgrouns slide up to hide and shows white text.
Any help or tips to learn how to do this would be greatly appreciated! :-)
var lastScrollTop = 0;
$(window).on('scroll', function() {
var header = $('.header');
var stage0 = $('.stage-0');
var scrollTop = $(window).scrollTop();
if (scrollTop > lastScrollTop) {
// down scroll
if (scrollTop > stage0.offset().top + stage0.height()) {
header.addClass('hide');
}
} else {
// up scroll
if (scrollTop <= stage0.offset().top + stage0.height()) {
header.removeClass('headerBGchange headerLIchange');
} else {
header.removeClass('hide').addClass('headerBGchange headerLIchange BGupTranistion');
}
}
lastScrollTop = scrollTop;
});
.header {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
height: 80px;
-webkit-transition: top .5s ease;
transition: top .5s ease;
position: fixed;
width: 100%;
top: 0;
background-color: transparent;
overflow: hidden;
}
.header ul {
margin: 20px;
padding: 0;
}
.header ul li {
display: inline-block;
margin-right: 20px;
color: white;
}
.header ul li:last-child {
margin-right: 0;
}
.hide {
top: -80px;
}
.headerBGchange {
Background: white;
}
.BGupTranistion {
}
.header.headerLIchange ul li {
color: Blue;
}
.header.headerLIchange {
border-bottom: 1px solid black;
}'
</style>
<!--stage style--><style>
.stage {
color: #fff;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
height: 100vh;
background-color: white;
border-bottom: 1px solid black;
font-size: 48px;
height: 200px;
width: 100%;
}
.stage-0 {
background: grey;
}
.stage-24 {
background: #433937;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div class="header">
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
<div class="stage stage-0">1</div>
<div class="stage stage-2">3</div>
<div class="stage stage-4">5</div>
<div class="stage stage-6">7</div>
<div class="stage stage-8">9</div>
<div class="stage stage-10">11</div>
<div class="stage stage-12">13</div>
<div class="stage stage-14">15</div>
<div class="stage stage-16">17</div>
<div class="stage stage-18">19</div>
<div class="stage stage-20">21</div>
<div class="stage stage-22">23</div>
You will need to add another container to achieve the effect you're looking for. What you essentially want to have is a container at the top and another container which will fade in and out depending on your scroll behaviour. So how do you achieve that? Create a -Element on top of the page, like your gray box is there at the moment. When scrolling down, do not transform it, instead, fade in another previously hidden container to act as your navigation when not at the top of the page. Now if you scroll back up, check the scroll location, and if the two locations of both containers overlap, start fading out the container you use when not at the top of the page. I do not think there is another solution. I might try and write a codepen on it now, I will edit my post if I had success. You could also try working it out with another div inside the actual header and z-index, though that might turn out really bad.
I have done my best to achieve what you want. Here is the CodePen.
I used two different divs, one called .dynamic-header and one normal header, and I've added a function to detect jQuery In-Viewport.
$.fn.isOnScreen = function(){
var element = this.get(0);
var bounds = element.getBoundingClientRect();
return bounds.top < window.innerHeight && bounds.bottom > 0;
}
I hope this fits your needs. Also, I changed some CSS around, using the Top-Property for the transition. You can outsource all of that into CSS classes and use them instead, but I thought this was the simplest solution for demonstration purposes. Is this what you want?
Edit 1: You named bartaile.com as an example. I took a look at the effect they create and recreated it. What you have to do is basically create a structure like this:
<div class="header-bg"></div>
<div class="header-content">
<ul>
<li>YOUR HEADER</li>
</ul>
</div>
I made another CodePen for this.
The header-bg has a height of 0. The header-content has a height of, lets say, 80px, and a background-color of transparent. Now do NOT check which direction is scrolled. The only important aspect for the effect is, how far are you from the top / is a specific element in viewport? I went for 400px from top. Now when that requirement is met, just fade in the header-bg. It will be inbetween the wrapper and the content, and will provide a background. Together with that, you may also change the color of the header-content, but I did not do that. It is what bartaile.com does, tho, so you might want to include it. Enjoy!
Edit 2: I've edited the CodePen according to your comment. See it in action here. This does the following: A header is there. When scrolling down, it'll disappear. On scroll up, it'll bring up a background, but when scrolling so that scrollTop < 400, the background will fade out. As of what I understood, this is what you want. It uses the structure I posted above.
I check out "bartaile.com" and I have to point out that what they use is a third party lib called 'fullpage'.If you wanna achieve that kind of effect, you should check out this lib fullpage.js. This is a simple and easy to use plugin to create fullscreen scrolling websites (also known as single page websites or onepage sites). It allows the creation of fullscreen scrolling websites, as well as adding some landscape sliders inside the sections of the site.
This plugin can handle "full screen scrolling" and also normal scrolling. You can achieve your effect with this much more easier

Categories

Resources