Transform element to fit height (Angular, SCSS) - html

I am writing a component that accepts a TemplateRef as in #Input() and renders it at some location within the component. The template appears in a container div that has a given width and height that don't necessarily match the aspect ratio of the template. My goal is to stretch (distort) the template to fit the container.
<div class="box-content box-background box-template-container">
<ng-container *ngTemplateOutlet="boxTemplate; context: { box: box }">
</ng-container>
</div>
I found what is necessary in the SCSS to make this work:
.box-template-container {
> ::ng-deep * {
transform-origin: top left;
transform: scale(1, 2);
}
}
The problem is this only works when the container is twice as high as the template, so I need to make the 2dynamic somehow. That's what I am looking for and cannot find. The challenge is the ::ng-deep partm the scale value is something I could calculate in a function.
Does anyone know how to do this or knows a better way of doing it?
I created a Stackblitz to demonstrate

Not sure what supposed to be inside the template but in general the approach feels wrong.
Probably something like this should be just enough:
.box-template-container::ng-deep > * {
width: 100%;
height: 100%;
}
or more complex:
.box-template-container {
position: relative;
}
.box-template-container::ng-deep > * {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}

Related

Style a banner card | HTML, CSS

How do you make the position: absolute; position: relative; stay together but have an auto height
I am trying to make profile cards in the style of Discord (latest design). When trying to show both the banner and a banner color it isn't aligned correctly. If anyone could help me, please?
Screenshot 1
Screenshot 2
To debug I tried to use CSS data selectors (\[data-??='true'\])
.preview-card.pfp[data-prem='True'] img {
top: 85px;
}
.preview-card .pfp[data-prem='False'] img {
top: 50px;
}
Yesm this will work but not for everything.
I think you have a space missing. Try this maybe:
.preview-card .pfp[data-prem='True'] img {
top: 85px;
}
.preview-card .pfp[data-prem='False'] img {
top: 50px;
}

Opacity on background image

As far as I know I can't directly change the opacity of a background image but using ::before and ::after doesn't seem to let my image show up. Am I doing it wrong?
HTML
flower window boxes
All of our products come in virtually any length up to 16 feet and two sizes. Our standard size boxes are designed to accommodate almost any flower. Our XL sizes are taller and deeper to provide more root space for plants making them the ideal sized window boxes for plants.
</div>
<div class="card-back">
<h2 class="click-here"><b>Visit Site</b></h2>
<div class="info">
<h2 class="info">Email:</h2>
<h2 class="info">Phone:</h2>
</div>
</div>
<!-- Content -->
<div class="all-content">
<h1>Contrary to popular belief</h1>
</div>
</li>
Current CSS
.content li:nth-child(1) .card-back{
background-image:url(../images/sponsor-imgs/Cellular%20PVC%20Columns-Kingston-1.jpg);
width: 100%;}
What I've tried
.backimg::after {
background-image:url(../images/backimg/wide.png);
opacity: 0.5;
}
.backimg::before{
background-image:url(../images/backimg/wide.png);
opacity: 0.5;
}
div::after {
opacity: 0.5;
}
On a side not i know i can simply make the images themselves transparent, but i feel like a code to do it much more useful in the long run. thanks in advance.
::before and ::after require a content property. You can set it to an empty string but it must be included.
In most cases you also need to define a display property and assign some dimensions to the element (unless you are using something like position: absolute; top: 0; bottom: 0; left: 0; right: 0; - in which case, you don't).
.backimg {
background: red;
}
.backimg::after {
content: "";
display: block;
width: 200px;
height: 200px;
background-image: url(http://placehold.it/200x200);
opacity: 0.5;
}
<div class="backimg"></div>
You are missing the .backimg class in your html.
Dont use double :: and add content and display properties to after. Also some dimensions wouldnt hourt (width,height)
.class:after{
Cintent:"";
Display:block; // change as you see fit
}

Place a div over another div without position: absolute or relative and variable height and width

I am making an application that uses a website as an interface.
The html look like the following:
setTimeout(function() {
$('#page-1').removeClass("show-me");
$('#page-2').addClass("show-me");
}, 1000);
setTimeout(function() {
$('#page-2').removeClass("show-me");
$('#page-3').addClass("show-me");
}, 2000);
div#main {
position: absolute;
min-width: 300px;
width: 100%;
height: 100%;
background-color: #ffa;
}
div#main > div {
position: absolute;
top: 0;
left: 0;
opacity: 0;
visibility: hidden;
transition-delay: 0s;
transition-duration: 200ms;
transition-property: "opacity,visibility";
transition-timing-function: ease;
}
#page-1 {
background-color: #00f;
}
#page-2 {
background-color: #0f0;
}
#page-3 {
background-color: #f00;
}
div#main > div.show-me {
opacity: 1;
visibility: visible;
}
<div id="main">
<div id="page-1" class="show-me">Page 1</div>
<div id="page-2">Page 2</div>
<div id="page-3">Page 3</div>
</div>
Each page contains data the same way as you would navigate to www.example.com/page-1, www.example.com/page-2 or www.example.com/page-3.
However I want to stay at www.example.com and navigate trough pages by fading them in and out.
I got them placed over one another with position: absolute;top:0;left:0; but this way main won't know the height of the page since it's content is absolute.
Therefore i'd like a way to make them fade in and out wiouth the use of position or negative margins (since the height of each page is dynamic due to content)
Or maybe you have another way of achieving this effect?
This is for an application, not a webpage that should be indexed by google or something else. So no SEO worries :)
EDIT:
Added a better example.
I would have to recomend jQuery Mobile library for this. It's pretty much what it was built for. I have been using it recently to make a custom app for our company and it's really quite good. Although a little bit tricky to pick up initially it's not as steep a learning curve as some other libraries I have used in the past.
(would have made this a comment, but I cant :-( )
Solved the problem by adding position: static; to the 'show-me' class.
This way the main knows the height of it's 'active' child!
When navigating first the active page class 'show-me' is removed, so it becomes position absolute again and starts to fade-out.
The next page gets the class 'show-me'.
Now becomes static so the main knows the new page's height and follows it.
And the new page fade's in as it should!
For a short moment (which you cannot see as far as I tested) the main div has no content and becomes small again. If it contains a background image you may see a little flicker but I think it's to fast for that so it shouldn't be noticeable.

How to rotate text and position it properly? (CSS, HTML)

I am trying to position a rotated headline next to some text. Statically it works very easy with absolute positioning (left picture). I have, however, difficulties when the page gets resized and the positioning fails (right picture).
Current CSS (can be changed):
.headline {
white-space: nowrap;
position: absolute;
top: 185px;
left: -20px;
transform: rotate(270deg);
}
Current HTML structure (can be changed):
<header>
<h1 class="headline">Über mich</h1>
</header>
<div class="text">
<p class="introduction">....</p>
</div>
How can I position the element so that I always stays 20px next to the paragraph?
Could someone link me to existing patterns how to solve this?
A solution with JS (and jQuery) would an option, I would, however, obviously prefer CSS.
Had the same issue. Managed to solve it like this in pure CSS :
.parent {
position: relative;
}
.child {
position: absolute;
transform: translateX(-100%) rotate(-90deg);
transform-origin: right;
left: 30px; /* change this value to match needs */
top: 30px; /* change this value to match needs */
}
The solution was a combination of Diego's answer and Smamatti's comment:
I had to use transform-origin:bottom and width:0. That was working rather quickly, the big problem I had was positioning the text independently to the length of the text. I've only managed to do this by using javascript.
.header
{
margin: 0;
width: 0;
white-space: nowrap;
position: absolute;
text-align: left;
transform-origin: bottom;
margin-top: 280px;
transform: rotate(270deg);
}
Javascript (to ensure compatibility to variables text length):
function adjustSideHeader() {
//check if the headline is visible
if($('h1.headline').length > 0)
{
var headline = $('h1.headline')[0];
var stringLength = headline.textContent.length;
//add style tag to support media queries
document.querySelector('style').textContent +=
"h1.headline { margin-top: " + (stringLength*23.5) + "px; -webkit-transition: margin-top 2s; transition: margin-top 2s;}"
}
}
// fire it when document is loaded
$(document).ready(setTimeout(adjustSideHeader, 300));
Result:
Have you tried moving
<h1 class="headline">Über mich</h1>
inside
<div class="text">?
and set
.text {
position: relative;
}
so that the position is relative to to "text" div. After that you might want to move the Über mich text to the left by reducing it's left value.
Have you tried use position:relative and the margin property?, I suppose it would be something like this:
.headline {
white-space: nowrap;
position: relative; //changed
margin-top: 185px; //changed
margin-left: -20px; //changed
transform: rotate(270deg);
}
*Note: I think you should move the headline inside the paragraph
I have an answer that may be late but worked wonderfully for me.
Normally your text will have a class or id and it will be position:absolute, and positioning values after it, like so:
.TextClass{
position:absolute;
top:50%;
left:55%;
transform:rotate(-90deg);
etc.
However, when you rotate, the positioning becomes relative (as mentioned above).
I found out that by simply putting the rotated text inside a parent div, you can position the (unrotated, position absolute) parent div as much as you want, and then rotate the text (which will be position:relative) inside the parent div, like so:
.divname{
position:absolute;
top:50vh;
left:50vw;
}
.TextClass{
position:relative;
transform:rotate(-90deg);
}

less mixin or selector to change position based on sibling index?

I'm trying to adjust the position of several sibling divs based on which sibling they are. Currently, they're all position: absolute, but that's not set in stone.
They are each a few hundred pixels tall, but I want them to overlap each other so that the ones behind only 'peek' out above the ones in front by a few pixels. The easiest way I can think of to do this would be a Less mixin for nth-of-type that, instead of only applying the rules to the matching one index, instead passes the index into the mixin. Basically, I want this:
&:nth-of-type(#n) {
top: #n * 20px;
}
Edit: what I'm currently doing:
&:nth-of-type(1) {
.card_offset(1);
}
&:nth-of-type(2) {
.card_offset(2);
}
&:nth-of-type(3) {
.card_offset(3);
}
&:nth-of-type(4) {
.card_offset(4);
}
Obviously this is nonoptimal. Is there a better way to do this in Less?
Alternatively, is there a CSS field for something like 'layout-height' that would give the div a certain height (not its full height) in the layout?
Assuming you know the number of elements in advance (or are recalculating your css on the fly somehow), then essentially what you have works if put into a loop structure which I originally discovered here on stack overflow.
LESS Code
.loop(#index) when (#index > 0) {
//set top amount
&:nth-of-type(#{index}) { //NOTE: 1.3.3 and under is just #index, not #{index}
top: #index * 20px;
}
// next iteration
.loop(#index - 1);
}
// end the loop when index is 0
.loop(0) {}
.yourElem {
#n: 6; //num of elements (could skip this and just put number in)
.loop(#n);
}
Outputs
.yourElem:nth-of-type(6) {
top: 120px;
}
.yourElem:nth-of-type(5) {
top: 100px;
}
.yourElem:nth-of-type(4) {
top: 80px;
}
.yourElem:nth-of-type(3) {
top: 60px;
}
.yourElem:nth-of-type(2) {
top: 40px;
}
.yourElem:nth-of-type(1) {
top: 20px;
}
I don't see a way that this is possible. Would be pretty cool, but I guess that's what javascript is for.
$('.parentDiv').children('div').each(function() {
$(this).css({"top": num * 20 + "px"});
num = num + 1;
});
Here's the full js solution:
http://jsfiddle.net/VbuQ9/
You can play around with the LESS fiddle here if you want.
http://jsfiddle.net/hV8sX/1/