I want to ask if it is possible to make the embedded airnbnb listing responsive? I am using this code for the sharing of listing:
<div class="airbnb-embed-frame" data-id="133213" data-view="home" data-hide-price="true" style="max-width:450px;width:100%;min-height:300px;height:100%;margin:auto;"><span>View On Airbnb</span>1 BR APT + 1 LIVING RM # SKYWALK CONDO (24th)<script async="" src="https://www.airbnb.com/embeddable/airbnb_jssdk"></script></div>
The container was responsive but the content of iframe is not. It only shows horizontal and vertical scroll.
I've found a workaround, not sure how well it holds up though.
Here's a codepen.
Basically, what I've done is calculate the scale by doing client width - 10 (for some margin on the right site) divided by the embedded div's width, then used that to transform it to the fitting size and set the origin to left in order to center it.
CSS:
.room-container {
display: flex;
flex-flow: row wrap;
}
.room {
width: 450px;
height: 300px;
margin: auto;
}
#media all and (max-width: 500px) {
.room-container {
flex-direction: column;
}
.room {
transform-origin: left;
}
}
JS:
(function () {
const resize = () => {
let rooms = document.getElementsByClassName('room');
for (let room of rooms) {
let scale = (window.innerWidth - 15) / room.offsetWidth;
room.style.transform = 'scale(' + scale + ')';
}
}
window.onload = () => resize();
window.onresize = () => resize();
})();
Thanks #AesopChris. I had some problems with responsiveness on Andoid devices, so I made few changes and it worked perfectly in WordPress and Elementor Page builder.
JS in Footer:
<script>
(function () {
const resize = () => {
let rooms = document.getElementsByClassName('airbnb-embed-frame');
for (let room of rooms) {
if ( window.innerWidth < 500 ) {
let scale = (screen.width - 20) / room.offsetWidth;
room.style.transform = 'scale(' + scale + ')';
} else {
room.style.transform = 'scale(1)';
}
}
}
window.onload = () => resize();
window.onresize = () => resize();
})();
</script>
Related
AngularJS newbie here. Is there a way to compute for a specific area in the page using AngularJS and/or CSS?
Basically what I'm trying to achieve is filling up the blank space below the last item of the navigation menu. I don't want for it to overlap with the footer. Reason why I want to compute for it is for it to adjust whenever user zooms out of the page.
This was my earlier attempt:
HTML
<div class="blankSpace">
CSS
div.blankSpace {
background-color: #35444f;
background-repeat: repeat-y;
}
... but this didn't work.
Any tips will be very much appreciated.
Thank you.
You can do this by using css3 or Angular directive.
// CSS
// Assume your header and footer height are 100px respectively.
#sidebar {
height: -moz-calc(100% - (100px + 100px));
height: -webkit-calc(100% - (100px + 100px));
height: calc(100% - (100px + 100px));
}
yourAppName.directive('sidebar', ['$document', '$window', function ($document, $window) {
return {
restrict: 'AE',
link: function (scope, element, attrs)
{
angular.element(document).ready(function () {
var headerHeight = 100px;
var footerHeight = 100px;
var d = $document.height() - headerHeight - footerHeight;
scope.changeHeight = function() {
element.css('min-height', d );
console.log(d);
};
scope.changeHeight();
});
}
};
}]);
// HTML Code Or Directive
<aside sidebar></aside>
I have a rails app that's loading external websites (mostly articles) inside an iframe. And I've gotten the majority of the articles to be responsive on any device. I'm only having trouble with articles from certain websites on mobile Safari.
Examples:
1. http://vyrtex-staging.herokuapp.com/article/what-went-wrong-in-flint
2. http://vyrtex-staging.herokuapp.com/article/built-on-passion-how-vox-media-grew-from-its-roots-as-an-oakland-a-s-blog-into-one-of-the-internet-s-biggest-publishers
3. http://vyrtex-staging.herokuapp.com/article/why-isn-t-america-paying-attention-to-trevor-noah
Here is what each of those look on mobile safari:
1. http://i.imgur.com/UAsiJD3.jpg
2. http://i.imgur.com/QgYiOsp.jpg
3. http://i.imgur.com/4wg8y9w.jpg
They look completely fine on desktop Safari, and desktop/mobile Chrome — only mobile Safari is the issue.
Here's my CSS:
.body_container {
width:100%;
height: 100vh;
padding-top:5px;
position: relative;
background-color: white;
}
.intrinsic-container {
position: relative;
height: 0;
-webkit-overflow-scrolling: touch !important;
overflow: scroll !important;
}
.intrinsic-container iframe {
position: absolute;
top:0;
left: 0;
width: 100%;
height: 100%;
border: 0;
}
Here's my HTML:
<div class="body_container">
<div class="intrinsic-container">
<iframe src="<%= #article.url %>"></iframe>
</div>
</div>
And here the javascript I'm running to keep the iframe responsive (the iframe itself, not necessarily the content inside of it):
<script>
var $iframes = $( "iframe" );
// Find & save the aspect ratio for all iframes
$(".intrinsic-container").each(function () {
$( this ).data( "ratio", this.height / this.width )
// Remove the hardcoded width & height attributes
.removeAttr( "width" )
.removeAttr( "height" );
});
$(document).ready( function () {
$(".intrinsic-container").each( function() {
// Get the parent container's width
var width = $( this ).parent().width();
var height = $( this ).parent().height() - $("#navbar").height();
var ratio = height / width;
var ratioString = String(ratio*100)+"%";
$(this).css('padding-bottom',ratioString)
$( this ).width( width )
.height( width * $( this ).data( "ratio" ) );
});
});
// Resize the iframes when the window is resized
$( window ).resize( function () {
$(".intrinsic-container").each( function() {
// Get the parent container's width
var width = $( this ).parent().width();
var height = $( this ).parent().height() - $("header").height();
var ratio = height / width;
var ratioString = String(ratio*100)+"%";
$(this).css('padding-bottom',ratioString)
$( this ).width( width )
.height( width * $( this ).data( "ratio" ) );
});
// Resize to fix all iframes on page load.
}).resize();
</script>
I'm guessing this is probably a CSS issue, where I have to add some webkit stuff to make sure the content inside the iframe loads responsively. Any thoughts on how I can fix this?
when it comes to wrap point how can we add animation?
maybe this can help:
we have a header and inside of that header we have container with flex attr and the direction is column when we resize our browser from bottom to top or when we changing height of browser those items suddenly reshape , I just want to add animation to this event.thx
<header>
<div class="container">
<div class="item1 item"></div>
<div class="item2 item"></div>
<div class="item3 item"></div></div></header>
header {
width: 200vw;
max-height: 100vh ;
}
.container{
display: flex;
max-height:100vh;
flex-direction: column;
flex-wrap: wrap;
align-content:flex-start;
}
.item1 {
background-color: red;
height: 200px;
flex: 1 0 150px;
}
.item2 {
background-color: blue;
height: 200px;
flex: 1 0 150px;
}
.item3 {
background-color: orange;
height: 200px;
flex: 1 0 150px;
}
I had a similar need and created a simple utility to achieve it.
- Demo at CodePen: https://codepen.io/hideya/pen/Jamabx
- GH gist: https://gist.github.com/hideya/16ed168a42f74eb5d2162b4e743940ff
The implementation is a bit wild and pretty much assumes no change in flex items except xy coords. You may need to adjust z-index, as it switches item's 'position' to 'absolute'.
Hope this helps.
window.addEventListener('load', function(event) {
var targetClassName = 'flex-wrap-anim';
var defaultDuration = '0.3s';
var dummyList = [];
function addDummy(item, duration) {
var top = item.offsetTop;
var left = item.offsetLeft;
setTimeout(function() {
item.style.position = 'absolute';
item.style.top = top + 'px';
item.style.left = left + 'px';
var dummyDiv = document.createElement('div');
dummyDiv.classList.add(targetClassName + '-dummy');
var rect = item.getBoundingClientRect();
dummyDiv.style.width = rect.width + 'px';
dummyDiv.style.height = rect.height + 'px';
dummyDiv.style.visibility = 'hidden';
dummyDiv['__' + targetClassName + '_pair'] = item;
dummyDiv['__' + targetClassName + '_duration'] = duration;
item.parentNode.appendChild(dummyDiv);
dummyList.push(dummyDiv);
}, 0);
}
var conts = document.getElementsByClassName(targetClassName);
for (var i = 0, max = conts.length; i < max; i++) {
var cont = conts[i];
cont.style.positoin = 'relative';
var duration = cont.getAttribute('data-duration')
|| defaultDuration;
var items = cont.getElementsByTagName('div');
for (var i = 0, max = items.length; i < max; i++) {
addDummy(items[i], duration);
}
}
window.addEventListener('resize', function(event) {
dummyList.forEach(function(dummyDiv) {
var item = dummyDiv['__' + targetClassName + '_pair'];
var duration = dummyDiv['__' + targetClassName + '_duration'];
if (item.offsetTop != dummyDiv.offsetTop) {
item.style.transition = 'all ' + duration;
item.style.top = dummyDiv.offsetTop + 'px';
item.style.left = dummyDiv.offsetLeft + 'px';
} else {
item.style.transition = '';
item.style.left = dummyDiv.offsetLeft + 'px';
}
});
});
});
While this cannot be done with CSS alone, you can accomplish this using JQuery. When looking at a flexbox using rows, the flexbox will change height if a new row is created or removed. Knowing this, we can add a .resize() function to the page to test if a window resize has altered the height of the flexbox. If it has, you can then execute an animation. I have created an example JFiddle here.
Here is the code that makes this work:
$(document).ready(function() {
var height = $('.container').css('height');
var id;
$(window).resize(function() {
clearTimeout(id);
id = setTimeout(doneResizing, 500);
});
function doneResizing() {
var newheight = $('.container').css('height');
if (newheight != height) {
$('.item').fadeOut();
$('.item').fadeIn();
height = newheight;
}
}
});
Now with a flexbox using columns, we need to detect when a change in width occurs. This is slightly more difficult as the flexbox width will take up the maximum allotted width as it is a block style element by default. So to accomplish this, you either need to set it as an inline flexbox using display: inline-flex, or set a maximum width for the flexbox equal to the width of its contents at its largest. Once you have set one of those, you can use the same code as above, except tweaking it to detect changes in width as opposed to height.
These changes applied an animation to all elements on resize. What if you want to only apply it to the element whose row/column changes? This would take more effort but is do-able. You would need to write many if-statements in your javascript/jquery code to catch which flex-item to apply the animation to based on width/height.
I'm not sure if "sticky" is the term for this, but is there a way to make the scrollbar from overflow:auto stay visible?
I have a rather large table that I want to be scrollable horizontally; however, the table is fairly tall as well, so when the page loads the horizontal scrollbar is not within the viewport of the browser, so it's rather hard to tell that the table is scrollable at all.
<div style = 'width:900px;overflow:auto'>
<table>
<!-- Very large table here -->
</table>
</div>
The scroll bar appears below the table, but unfortunately the table is so tall you can't see it unless you scroll down.
I'd like to have the horizontal scrollbar stay visible even if the table goes off the screen, maybe fixed to the bottom of the viewport. Ideally I'd like to do it using only CSS or a minimal amount of javascript.
Here is a script for that http://jsfiddle.net/TBnqw/2288/
$(function($){
var scrollbar = $('<div id="fixed-scrollbar"><div></div></div>').appendTo($(document.body));
scrollbar.hide().css({
overflowX:'auto',
position:'fixed',
width:'100%',
bottom:0
});
var fakecontent = scrollbar.find('div');
function top(e) {
return e.offset().top;
}
function bottom(e) {
return e.offset().top + e.height();
}
var active = $([]);
function find_active() {
scrollbar.show();
var active = $([]);
$('.fixed-scrollbar').each(function() {
if (top($(this)) < top(scrollbar) && bottom($(this)) > bottom(scrollbar)) {
fakecontent.width($(this).get(0).scrollWidth);
fakecontent.height(1);
active = $(this);
}
});
fit(active);
return active;
}
function fit(active) {
if (!active.length) return scrollbar.hide();
scrollbar.css({left: active.offset().left, width:active.width()});
fakecontent.width($(this).get(0).scrollWidth);
fakecontent.height(1);
delete lastScroll;
}
function onscroll(){
var oldactive = active;
active = find_active();
if (oldactive.not(active).length) {
oldactive.unbind('scroll', update);
}
if (active.not(oldactive).length) {
active.scroll(update);
}
update();
}
var lastScroll;
function scroll() {
if (!active.length) return;
if (scrollbar.scrollLeft() === lastScroll) return;
lastScroll = scrollbar.scrollLeft();
active.scrollLeft(lastScroll);
}
function update() {
if (!active.length) return;
if (active.scrollLeft() === lastScroll) return;
lastScroll = active.scrollLeft();
scrollbar.scrollLeft(lastScroll);
}
scrollbar.scroll(scroll);
onscroll();
$(window).scroll(onscroll);
$(window).resize(onscroll);
});
It is a quick test rather than a complete generic plugin, but is a good start, I think
Here's my take, #user2451227's is almost perfect, but didn't work with nested overflowed elements and had a number of performance issues, so I rewrote it:
$(function($){
var fixedBarTemplate = '<div class="fixed-scrollbar"><div></div></div>';
var fixedBarCSS = { display: 'none', overflowX: 'scroll', position: 'fixed', width: '100%', bottom: 0 };
$('.fixed-scrollbar-container').each(function() {
var $container = $(this);
var $bar = $(fixedBarTemplate).appendTo($container).css(fixedBarCSS);
$bar.scroll(function() {
$container.scrollLeft($bar.scrollLeft());
});
$bar.data("status", "off");
});
var fixSize = function() {
$('.fixed-scrollbar').each(function() {
var $bar = $(this);
var $container = $bar.parent();
$bar.children('div').height(1).width($container[0].scrollWidth);
$bar.width($container.width()).scrollLeft($container.scrollLeft());
});
$(window).trigger("scroll.fixedbar");
};
$(window).on("load.fixedbar resize.fixedbar", function() {
fixSize();
});
var scrollTimeout = null;
$(window).on("scroll.fixedbar", function() {
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(function() {
$('.fixed-scrollbar-container').each(function() {
var $container = $(this);
var $bar = $container.children('.fixed-scrollbar');
if($bar.length && ($container[0].scrollWidth > $container.width())) {
var containerOffset = {top: $container.offset().top, bottom: $container.offset().top + $container.height() };
var windowOffset = {top: $(window).scrollTop(), bottom: $(window).scrollTop() + $(window).height() };
if((containerOffset.top > windowOffset.bottom) || (windowOffset.bottom > containerOffset.bottom)) {
if($bar.data("status") == "on") {
$bar.hide().data("status", "off");
}
} else {
if($bar.data("status") == "off") {
$bar.show().data("status", "on");
$bar.scrollLeft($container.scrollLeft());
}
}
} else {
if($bar.data("status") == "on") {
$bar.hide().data("status", "off");
}
}
});
}, 50);
});
$(window).trigger("scroll.fixedbar");
});
Usage: Add the class fixed-scrollbar-container to your horizontally overflowed element, then include this code. If the container is updated or changes in size, run $(window).trigger("resize.fixedbar"); to update the bar.
Demo: http://jsfiddle.net/8zoks7wz/1/
#Mahn - I made a small update to the following function:
$('.fixed-scrollbar-container').each(function() {
var container = jQuery(this);
if (container[0].offsetWidth < container[0].scrollWidth) {
var bar = jQuery(fixedBarTemplate).appendTo(container).css(fixedBarCSS);
bar.scroll(function() {
container.scrollLeft(bar.scrollLeft());
});
bar.data("status", "off");
}
});
The if statement looks if the container offsetWidth is smaller than the scrollWidth. Else you will also get a fixed scrollbar if the content happens to be smaller than the container. I did not like having a disfunctional scrollbar, hence this edit.
How about restricting the height of the containing div so it stays within the body? You could then have the table scroll within that div.
Working jsfiddle here: http://jsfiddle.net/fybLK/
html, body {height: 100%; margin: 0; padding: 0;}
div {
width:500px;
max-height: 100%;
overflow:auto;
background: steelblue;}
table {
width: 1000px;
height: 1000px;
color: #fff;}
Here, I've set the html and body to 100% height so that the containing div can be sized.
I have two CSS classes:
.class1 {
height: 100%;
width: 300px;
border: 1px none #B0B0B0;
position: relative;
display: inline;
left: 10px;
}
.class2 {
height: 100%;
width: 200px;
position: relative;
display: inline;
margin-left: 15px;
background-color: #00CCCC;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-style: solid;
border-right-style: solid;
border-bottom-style: solid;
border-left-style: solid;
}
Now, as you can see, they're both set to display in a line (no line breaks in between elements). Which works correctly. But for some reason, ever since I set the display to inline, the Padding, the Positioning and the Margin CSS have all just stopped working. I can add a margin-left 10inches and nothing will happen. Same with padding and positioning.
Can anyone explain how to fix this?
Also, I have the relative position set on both classes, yet when viewing the page in a browser, .class2 over laps .class1 when its supposed to be just after .class1.
Any ideas?
EDIT:
Okay, so I've done a JSFiddle, but it seems to be playing up even more there....
Looks like the Width is not working....
here it is:
http://jsfiddle.net/zYbwh/1/
You need to use
display: inline-block;
instead. margin doesn't work with display: inline elements, however with inline-block it does. You can then have an inline element with margins and explicit widths/heights.
To make this work in IE7, add these two lines:
*display: inline;
zoom: 1;
It's horrible, but it works.
I know this is quite a late answer but I wrote a jQuery plugin which support padding on inline elements (with word breaking) see this JSfiddle:
http://jsfiddle.net/RxKek/
Plugin Code:
$.fn.outerHTML = function () {
// IE, Chrome & Safari will comply with the non-standard outerHTML, all others (FF) will have a fall-back for cloning
return (!this.length) ? this : (this[0].outerHTML || (
function (el) {
var div = document.createElement('div');
div.appendChild(el.cloneNode(true));
var contents = div.innerHTML;
div = null;
return contents;
})(this[0]));
};
/*
Requirements:
1. The container must NOT have a width!
2. The element needs to be formatted like this:
<div>text</div>
in stead of this:
<div>
text
</div>
*/
$.fn.fixInlineText = function (opt) {
return this.each(function () {
//First get the container width
var maxWidth = opt.width;
//Then get the width of the inline element
//To calculate the correct width the element needs to
//be 100% visible that's why we make it absolute first.
//We also do this to the container.
$(this).css("position", "absolute");
$(this).parent().css("position", "absolute").css("width", "200%");
var width = $(this).width();
$(this).css("position", "");
$(this).parent().css("position", "").css("width", "");
//Don't do anything if it fits
if (width < maxWidth) {
return;
}
//Check how many times the container fits within the box
var times = Math.ceil(width / maxWidth);
//Function for cleaning chunks
var cleanChunk = function (chunk) {
var thisChunkLength = chunk.length - 1;
if (chunk[0] == " ") chunk = chunk.substring(1);
if (chunk[thisChunkLength] == " ") chunk = chunk.substring(0, thisChunkLength);
return chunk;
};
//Divide the text into chunks
var text = $(this).html();
var textArr = text.split(" ");
var chunkLength = Math.ceil((textArr.length - 1) / times);
var chunks = [];
var curChunk = "";
var curChunkCount = 0;
var isParsingHtml = false;
//Loop through the text array and split it into chunks
for (var i in textArr) {
//When we are parsing HTML we don't want to count the
//spaces since the user doesn't see it.
if (isParsingHtml) {
//Check for a HTML end tag
if (/<\/[a-zA-Z]*>/.test(textArr[i]) || /[a-zA-Z]*>/.test(textArr[i])) {
isParsingHtml = false;
}
} else {
//Check for a HTML begin tag
if (/<[a-zA-Z]*/.test(textArr[i])) {
isParsingHtml = true;
}
}
//Calculate chunks
if (curChunkCount == (chunkLength - 1) && !isParsingHtml) {
curChunk += textArr[i] + " ";
chunks.push(cleanChunk(curChunk));
curChunk = "";
curChunkCount = -1;
} else if ((i == (textArr.length - 1))) {
curChunk += textArr[i];
chunks.push(cleanChunk(curChunk));
break;
} else {
curChunk += textArr[i] + " ";
}
if (!isParsingHtml) {
curChunkCount++;
}
}
//Convert chunks to new elements
var el = $($(this).html("").outerHTML());
for (var x in chunks) {
var new_el = el.clone().html(chunks[x]).addClass("text-render-el");
var new_el_container = $("<div/>").addClass("text-render-container");
new_el_container.append(new_el);
$(this).before(new_el_container);
}
//Finally remove the current element
$(this).remove();
});
};
Thats the problem you get when using templates, ive programmed a site in php, but the design is killing me.
So i try'd some rocket fuel for webdesigners.
And this is the problems i keep getting every step of the way...
Inline-block does not work for me, nothing works, becouse it is not my design and i dont know the setup.
Ive tryd doing the design myself, but i am out of time, i need a design yesterday.
I suggest you take what u need from the templates and delete everything else, that will schrink your problem, and save you time.