Summary: My 90-degrees rotated text, put into rowspaned cell, is word-wrapped to two lines, though in my opinion, there is enough space in cell to write it in a single line. Is this some kind of browsers' bug?
Details: I have a single-one text, that I rotate 90 degrees:
.rotate-90-degrees
{
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0.083); /* IE6,IE7 */
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0.083)"; /* IE8 */
-moz-transform: rotate(-90.0deg); /* FF3.5+ */
-ms-transform: rotate(-90.0deg); /* IE9+ */
-o-transform: rotate(-90.0deg); /* Opera 10.5 */
-webkit-transform: rotate(-90.0deg); /* Safari 3.1+, Chrome */
transform: rotate(-90.0deg); /* Standard */
}
I then put it into a table cell, rowspaned to four rows:
<td rowspan="4">
<div class="rotate-90-degrees">
Quest. no 1
</div>
</td>
Browser (Chrome) renders div itself as 44px x 40 px, while table cell's as 61px x 148px with padding set to 8px. Though, I was pretty sure, that I'll get entire text in a single line, it is word-wrapped to two lines and produces quite ugly effect:
It seems, that there is enough space to write it in a single line. 44px div's width (which now becomes height, due to rotation) plus 2 x 8px padding is only 60px, which is still far, far less than cell's height set to 148 px. Why, then, it is being word-wrapped?
When I highlight cell (second on image) with Chrome Developers Tools, it seems to me, that browser is adding an enormous height padding to cell's content, completely ignoring CSS-set padding (8px). Or is there any other reason, that I just don't see?
I tried to "fix" this, by changing padding to 0 px or even negative value, but without any luck. Is there any way, that I can force browser to render this text in a single line, if there is space enough to fit it?
BTW: Tests and examples are made in Chrome, but effect in IE and Firefox is exactly the same.
Preventing wrapping in CSS is just:
white-space: nowrap;
(Other values may also be useful.)
Related
Is it possible to scale a child (of known size) to match the width of it's parent (of unknown width)?
The child's size will be wider that it's parent. I need to find a way to scale it down so that it displays the entire child within the bounds of the parent.
I am hoping to avoid using javascript if possible.
Here is the code:
.a-very-wide-child {
/* the exact size of the child is known */
width: 3000px;
height: 500px;
/* I am trying to scale this element to match the width of its parent. */
/* I am thinking probably what I need is a value for [HERE]. I am open
to other suggestions though. */
transform: scale(calc(/* [HERE] */));
transform-origin: top left;
/* I am NOT wanting to use width rules to resize the child. */
/* no: width: 100%; */
/* no: max-width: 100%; */
}
.a-small-parent {
/* has no style rules of note */
/* the width of the parent is not known */
/* the height of the parent is not known exactly, but known to be tall
enough to not be of concern */
}
/* Below is just styling and is safe to ignore. */
.a-small-parent {
border: 5px solid teal;
}
.a-very-wide-child {
background-image: linear-gradient(45deg, #888, transparent);
border: 5px solid gold;
}
.container{
width: 40vw;
}
<div class="container">
<div class=a-small-parent>
<pre class=a-very-wide-child>
<img src="https://picsum.photos/400/500" alt="">
</pre>
</div>
</div>
Off late, I have been fiddling with all kinds of element size and font scaling for responsive behavior and knew I had already created something to solve your issue (see Codepen links at the end).
To start with the downside: you cannot avoid using at least some Javascript as you will need a unitless scale factor for the CSS transform: scale(..) to function properly. And for responsiveness purposes, you will need to know the current clientWidth of the parent container. This is also true for container queries and their respective units. With CSS you just cannot strip units off a property value.
Equation for the scale factor: parent.clientWidth / child.Width (unitless).
When scaling down with transform: scale(..), HTML will continue to use the original space the element occupied in the document causing a (huge) space surrounding the element. Fiddling with transform-origin will not solve that issue, but with negative margins we can 'remove' the excess space and snuggly fit our element in its parent. The demo assumes default transform-origin: center, simply meaning that below equation is true for all four margin properties.
Equation for margin space offset: offset = -1px * (childSize - scaled childSize) / 2 (with 'px'-unit conversion). Because of the current issue we can suffice to address width values only, so childSize reads childWidth.
The snippet uses CSS custom variables in all equations for easy manipulation and testing. The code is heavily commented, so I expect little surprises there. Let me know if I need to elaborate on something.
Be aware that when slowly resizing the browser you will sometimes see blank, single pixel lines above/aside the scaled element. This is not the result of the above equation, but due to rounding issues I have not taken into account. With division in equations you will get decimal values eventually causing partial pixels. Rule of thumb: part of a pixel is a full pixel. This would require additional Javascript as CSS does not round(..), ceil(..) or floor(..).
Some Codepens with variations on scaling I have created:
a web page with a list of scaled down <iframe> elements made to look like cards Codepen: Runtime scaling cards, CSS only
and Codepen: SO75129247 (WIP) of a SO question I haven't gotten around to answer, incorporating the above Codepen as a nested <iframe>.
The snippet
// Assign event listeners to show scaling works on resize
window.addEventListener('load' , setVariables); // Initial run
window.addEventListener('resize', setVariables); // Reponsiveness scaling
// parent elements involved
const parents = document.querySelectorAll('.a-small-parent');
function setVariables() {
// Modify CSS custom variables to hold current element
// width/height per parent
parents.forEach((el) => {
el.style.setProperty('--parentClientWidth' , el.clientWidth);
el.style.setProperty('--parentClientHeight', el.clientHeight);
});
};
.a-small-parent {
/* has no style rules of note. CHECK! */
/* the width of the parent is not known. CHECK! */
/* the height of the parent is not known exactly, but known to be tall
enough to not be of concern. CHECK! */
/* [OPTIONAL] defined here, just for clarity */
--parentClientWidth : 0; /* Modified by JS */
--parentClientHeight: 0;
}
.a-very-wide-child {
/* the exact size of the child is known. CHECK! */
/* Define the size of the child element, unitless */
--childWidth : 3000; /* We need unitless values to */
--childHeight: 500; /* calculate scale and offset */
width : calc(var(--childWidth) * 1px); /* Could be hardcoded units */
height: calc(var(--childHeight) * 1px); /* like the original code */
/* Define the parent to child scale factors for the transform, unitless */
--scaleH: calc(var(--parentClientWidth) / var(--childWidth)); /* Horizontal */
/*
When in the below 'transform' functions scaleX(..) and scaleY(..)
are being used, two transform-scale variables must be declared and
used for scaling and margin offset calculation.
*/
--scaleV: var(--scaleH); /* For now, Horizontal/Vertical scales are equal */
/* I am trying to scale this element to match the width of its parent. */
/* I am thinking probably what I need is a value for [HERE]. I am open
to other suggestions though. CHECK! */
/* Scale the child element relative to current parent clientWidth and clientHeight */
transform: scale(var(--scaleH), var(--scaleV));
/* I am NOT wanting to use width rules to resize the child. CHECK! */
/* no: width: 100%; */
/* no: max-width: 100%; */
/*
'transform: scale(..)' scales an element but leaves the original space the element
occupied intact. Essentially, leaving a big open space after scale down, or a burst out
of the parent when scaling up.
Assuming the element is scaled down and uses default 'transform-origin: center'
we need to calculate margin offsets to correct the gaps:
T/B: offset = -1 * (childHeight - scaled childHeight) / 2
R/L: offset = -1 * (childWidth - scaled childWidth) / 2
- childHeight/childWidth offset as their values differ
- multiplied by -1 as we need a negative offset to shrink the gap
- divided by 2 as we must shrink either side (Top and Bottom, Right and Left)
The sign of below 'offset-unit-multiplier' depends on the current scale factor
- negative when scale factor < 1
- positive when scale factor > 1
This requires additional Javascript to determine (not implemented).
*/
/* Assumed to be 'negative' in this demo: always scaling down */
--offset-unit-multiplier: -1px;
--offsetTB: calc(var(--offset-unit-multiplier) * (var(--childHeight) - var(--scaleV) * var(--childHeight)) / 2);
--offsetRL: calc(var(--offset-unit-multiplier) * (var(--childWidth) - var(--scaleH) * var(--childWidth)) / 2);
margin: var(--offsetTB) var(--offsetRL);
/*
Moved down as it is not needed. However, when assigned here,
the calculations for the margin offset must be changed accordingly.
This would require some testing/fiddling to find out what works best.
*/
/* transform-origin: top left;/* Obsolete */
}
/* Below is just DEMO styling and is safe to ignore. */
* {
box-sizing: border-box;
outline: 1px dashed; /* for debugging */
}
pre { margin: 0 }
img { height: 100%; object-fit: cover }
.a-small-parent { border: 5px solid teal }
.a-very-wide-child { border: 5px solid red; background-image: linear-gradient(45deg, #888, transparent) }
.container { width : 40vw }
<div class="container">
<div class=a-small-parent>
<pre class=a-very-wide-child>
<img src="https://picsum.photos/400/500" alt="">
</pre>
</div>
</div>
I'm trying to create a vertical progress bar by using a CSS transform. I want the progress bar to take up the full height of the screen.
The problem is that, since I use CSS rotate, the progress bar's height is equal to the width of the screen, not its height. I created a fiddle to demonstrate this: the length of the progress bar will change depending on how wide you make the 'Result' section. This is incorrect: it should always take up the entire screen. Here's the code:
HTML:
<progress max="1" value="0.8"></progress>
CSS:
progress {
margin: 0;
height: 5px;
width: 100%;
-webkit-transform: rotate(90deg);
-webkit-transform-origin: bottom left;
-moz-transform: rotate(90deg);
-moz-transform-origin: bottom left;
/* Reset the default appearance */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
As it's a progress bar, its size cannot be larger than the screen height, otherwise the progress indication will be off. I've looked at this solution but this won't work for me because screen dimensions can change at anytime (e.g. switching between portrait and landscape on a tablet), so a JavaScript solution won't do.
Is there a way to force the progress bar to take up the full height of the screen using just CSS? Any other solution to create a vertical progress bar without using rotations, would also be great!
I'm not quite sure what you mean, however try replacing width:100%, with width:100vh;.
As #jaunt just said, using width: 100vh would do the trick, as it takes in consideration the viewport height to assign a width for the progress. Below you can find the list of browsers that support this:
http://caniuse.com/#feat=viewport-units
I've got a <span class="name"> next to an <img> inside a <div>. Inside this span I have some text which I want to turn 90 degrees. However, when I do this (as code suggests below) the span ends up in a somewhat weird position on top of the image.
In IE, the text doesn't rotate at all.
.name {
display: block;
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
}
Any suggestions as to how I solve this?
I've fixed this on my own what I needed to do was put a fixed size on the span and then use position:absolute; to position it where I wanted it
I'm not sure how to fix it. But the reason it doesn't rotate in IE is that you are using "webkit" and "moz" to rotate - which are firefox-like-browser specific functions. You'll have to google for an IE-equivalent.
I have this page and I have users uploading an icon image for the industries and they are uploading a bigger image. I want to resize it via CSS and it's cutting it when changing it in Firebug. To see what I mean, select "retail" from the top dropdown "Select Industry Category" and then select "General" from "Select Business Type" and you will see the oddly shaped image. It needs to be 56 pixels * 52 pixels.
Here is my HTML:
<span class="icon select-business-icon" style="background-image: url(http://posnation.com/shop_possystems/image/data/icons/retail.png);"> </span>
I tried in the CSS to set the width and height to the desired measurements, but all it did was truncate the image and not resize.
Here's what I've done:
.resize {
width: 400px;
height: auto;
}
.resize {
width: 300px;
height: auto;
}
<img class="resize" src="example.jpg"/>
This will keep the image aspect ratio the same.
You can resize images using CSS just fine if you're modifying an image tag:
<img src="example.png" style="width:2em; height:3em;" />
You cannot scale a background-image property using CSS2, although you can try the CSS3 property background-size.
What you can do, on the other hand, is to nest an image inside a span. See the answer to this question: Stretch and scale CSS background
CSS 3 introduces the background-size property, but support is not universal.
Having the browser resize the image is inefficient though, the large image still has to be downloaded. You should resize it server side (caching the result) and use that instead. It will use less bandwidth and work in more browsers.
You can try this:
-ms-transform: scale(width,height); /* IE 9 */
-webkit-transform: scale(width,height); /* Safari */
transform: scale(width, height);
Example: image "grows" 1.3 times
-ms-transform: scale(1.3,1.3); /* IE 9 */
-webkit-transform: scale(1.3,1.3); /* Safari */
transform: scale(1.3,1.3);
Normally, if I create:
<meter value="30" max="100">Low</meter>
I'll end up with a horizontal meter/bar if viewed on a browser that supports the html5 meter element.
Is it possible to create a vertical meter with html5?
The only solution I've been able to come up with so far is using CSS3 rotation (transform).
Yeah transform is the only way to do this..
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-o-transform: rotate(90deg);
transform: rotate(90deg);
Transform is the answer. The whole point of meter is that it's a semantic, not a presentational element and you should be able to style it however you want with CSS>
Using transform on the meter element has a major drawback which I have yet to find an elegant way around, it doesn't seem to change the amount of horizontal width the element requires. eg, for a meter with width 180px and height 15px transformed by 270deg, the meter will show as a vertical bar with height 180px and width 15px, but the bounding box ends up as 180x180 with a huge white space on the left side. Further CSS is then needed to reposition the element so the with gap is hidden. I've observed this behaviour on both Chrome and Firefox.