CSS: How to enforce width inside a dynamic width container? - css

First off, here's the fiddle: https://jsfiddle.net/u8v3rgyt/1/
The basic scenario is this: I have some text, which will vary in length. Below this text I have a column of (EDIT: a varying number of) buttons, which also have text that varies. What I want is for the text to control the overall width, and then have the button column adjust its width/its buttons' width in response. In other words, for two different sizes of text, I'm trying to achieve the following:
// Short text
La la la la
[Button 1
text]
[Button 2
with long
text]
// Longer text
La la la la la la la la la la
[Button 1 text]
[Button 2 with long text]
but I get:
// Short text
La la la la
[Button 1 text]
[Button 2 with long text]
I feel like I'm close, but I can't get the button container to have the correct width (and thus I can't limit my buttons' width). Or rather, I can, but to do so I have to put a fixed width on the text, and that doesn't work because I need the whole thing to adjust it's size based on the text.
Any help would be appreciated.

As I understand, you want the text to dictate the width of the area in which the buttons are laid out. Using the CSS3 flex box model you could do something along these lines:
.container {
display: inline-block;
border: 1px solid red;
margin-bottom: 24px;
}
.inner {
display: flex;
flex-wrap: wrap;
}
button {
flex-grow: 1;
}
<div class="container">
<p>Some text blah blah blah, blah blah blah</p>
<div class="inner">
<button>Button 1</button>
<button>Button 2</button>
</div>
</div>

Related

Right align title text inside Material Design Card

I'm using a Material Design (MDL) card to display numeric values in the title. I want them to be aligned right but by default they are left aligned. I've tried setting various styles but they all are ignored. How can I right align the h2 in the card title?
<div class="mdl-card card--count">
<div class="mdl-card__title mdl-card--expand">
<h2 class="mdl-card__title-text">
999
</h2>
</div>
<div class="mdl-card__supporting-text"><slot /></div>
</div>
text-align: right; won't work as .mdl-card__title is using flex, so you have to change the justify-content property:
.mdl-card__title {
justify-content: flex-end;
}
https://jsfiddle.net/f7ykzx1c/1/

Why is the descender “created” when baseline is set to vertical-align?

I know that the img element has a descender margin below it by default.
.box {
border: 1px solid;
}
<div class="box">
<img src="http://placehold.jp/150x150.png"> xyz
</div>
Question
I thought that the vertical-align property "aligns" elements at a specific position, so the height doesn't change. However, with the following code, when measuring the height when changing vertical-align, height was increased only forbaseline.
Why does it behave like "making a descender only when baseline"? Isn't a descender always present regardless of the value of the vertical-align property? There was no mention of this behavior in the vertical-align specification.
var align = ["top", "bottom", "baseline"];
var idx = 0;
function changeVerticalAlign() {
document.querySelector(".box>img").style.verticalAlign = align[idx];
document.querySelector("p").innerText = "height=" + getComputedStyle(document.querySelector(".box")).getPropertyValue("height") + ", vertical-align=" + getComputedStyle(document.querySelector(".box>img")).getPropertyValue("vertical-align");
idx < 2 ? ++idx : idx = 0;
}
document.querySelector("button").addEventListener("DOMContentLoaded", changeVerticalAlign);
document.querySelector("button").addEventListener("click", changeVerticalAlign);
.box {
border: 1px solid;
}
<div class="box">
<img src="http://placehold.jp/150x150.png"> xyz
</div>
<p></p>
<button>change vertical-align to "bottom"</button>
I thought that the vertical-align property "aligns" elements at a specific position, so the height doesn't change.
This isn't true because the height is defined after the alignment is done and you can clearly notice this if you use text instead of image:
.box{
border:1px solid;
margin:5px;
}
<div class="box">
<span>some text</span>
<span>some text</span>
<span>some text</span>
</div>
<div class="box">
<span style="vertical-align:super">some text</span>
<span>some text</span>
<span>some text</span>
</div>
<div class="box">
<span style="vertical-align:super">some text</span>
<span>some text</span>
<span style="vertical-align:sub">some text</span>
</div>
From the specification:
The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned. The rectangular area that contains the boxes that form a line is called a line box.
and also
A line box is always tall enough for all of the boxes it contains. However, it may be taller than the tallest box it contains (if, for example, boxes are aligned so that baselines line up). When the height of a box B is less than the height of the line box containing it, the vertical alignment of B within the line box is determined by the 'vertical-align' property.
Then in another part of the specification
As described in the section on inline formatting contexts, user agents flow inline-level boxes into a vertical stack of line boxes. The height of a line box is determined as follows:
The height of each inline-level box in the line box is calculated. ....
The inline-level boxes are aligned vertically according to their 'vertical-align' property. ....
The line box height is the distance between the uppermost box top and the lowermost box bottom. (This includes the strut, as explained under 'line-height' below.)
So basically the height is defined bigger enough to hold the content after being aligned that's why the height may increase for some alignment.
If you add border to your elements you will notice the uppermost box top and the lowermost box bottom.
var align = ["top", "bottom", "baseline","super","sub","text-bottom","text-top"];
var idx = 0;
function changeVerticalAlign() {
document.querySelector(".box>img").style.verticalAlign = align[idx];
document.querySelector("p").innerText = "height=" + getComputedStyle(document.querySelector(".box")).getPropertyValue("height") + ", vertical-align=" + getComputedStyle(document.querySelector(".box>img")).getPropertyValue("vertical-align");
idx < 6 ? ++idx : idx = 0;
}
document.querySelector("button").addEventListener("DOMContentLoaded", changeVerticalAlign);
document.querySelector("button").addEventListener("click", changeVerticalAlign);
.box {
border: 1px solid;
}
.box> * {
border:1px solid red;
}
p {
margin:0;
}
<div class="box">
<img src="http://placehold.jp/150x130.png"> <span>xyz</span>
</div>
<p></p>
<button>change vertical-align</button>

No line break between text and SVG

I have a short text that is followed by an SVG in a limited-width container.
The expected behaviour is that the text breaks if it's longer than the container width BUT I would like it NOT to break right between the text and the svg:
Current result:
Expected result:
Adding a <nobr> or a <span>tag in the middle of the text (before blue) and closing it after the SVG is not an option as the text comes from an external database and cannot be edited.
<span class="text">
Jack Wolfskin Jacke Colorado Flex - Midnight Blue
</span>
<span class="svg">
<svg>
....
</svg>
</span>
add display-block to svg container:
.svg {
display: inline-block;
}
The only solution I found required a nasty change in the origin HTML.
To make sure the icon is never alone in the new line I wrapped the last word and the icon in a new element with white-space: no-wrap;, plus if we want it to still split if the line cannot accommodate last word with the icon we can make this new container inline flex and flex-wrappable.
<div>
Lorem ipsum dolor sit
<span class="last_word">
very_long_last_word
<svg>...</svg>
</span>
</div>
.last_word {
/* Stick icon to last word */
white-space: no-wrap;
/* Make sure last word and icon will break ultimately */
display: inline-flex;
flex-wrap: wrap;
}
Live example: https://jsfiddle.net/uerzo6sa/
You can prevent the line breaking with this markup. It doesn't need to include the last word, so you can use it even with a generated content.
JSX
<div>
{children}
<span className="tail">
{'\u00a0'}
<svg></svg>
</span>
</div>
HTML
<div>
Lorem ipsum dolor sit<span class="tail"> <svg></svg></span>
</div>
CSS
.tail {
white-space: no-wrap;
}
https://jsfiddle.net/radarfox/65h40jt7/
You can add padding to the text and a negative margin:
<span class="text" style="padding-right: 15px;">
Jack Wolfskin Jacke Colorado Flex - Midnight Blue
</span>
<span class="svg" style="margin-left: -15px;">
<svg>
....
</svg>
</span>
That way, if there isn't room for the padding, the last word will get pushed to the next line also.
(This is based on this answer: https://stackoverflow.com/a/25857961/5899236)
You can define position: absolute on the SVG, with auto for top, right, etc.
https://codepen.io/jsit/pen/xxOQoVW
The only side-effect is this will allow the SVG to appear outside of the containing box; this is in a sense the reason it works at all.

Centring a div box when you cannot adjust html

I am trying to adjust the CSS so the "product" and product information is centered and not floated to the left I cannot adjust the HTML as its given via a shortcode thats added into the WP post but maybe I could wrap it in a div?
HTML:
<ul class="products ribbon">
<li class="product last first">
<a href="http://dailybabydeals.co.nz/shop/estella-rose-designs/">
<div class="thumbnail">
<span class="onsale">Sale!</span>
<img width="325" height="325" src="http://dailybabydeals.co.nz/wp-content/uploads/2013/02/Front-Page-325x325.jpg" class="attachment-shop_catalog wp-post-image" alt="Front Page" />
<div class="thumb-shadow"></div>
<strong class="below-thumb">Estella Rose Designs</strong>
</div>
<span class="price"><span class="from">From: </span><del><span class="amount">$25</span></del> <ins><span class="amount">$19.95</span></ins></span>
</a>
<div class="buttons">
Select options</div>
</li></ul>
CSS:
CSS
Okay, let's try this again now that I understand your question better. So you want to center the <ul> element as a whole? That is a lot simpler than what I originally thought you were going for.
To do that, all you need to do is wrap the <ul> element in a span tag that is set to display as an inline-block. Then set the containing element so that its text is centered.
Try this:
<html>
<head>
<style language="text/css">
/*<![CDATA[ */
#test1 {
text-align: center;
}
#test2 {
display: inline-block;
text-align: left;
}
/* ]]> */
</style>
</head>
<body>
<div id="test1">
<span id="test2">
<!-- Place your <ul> element here -->
</span>
</div>
</body>
</html>
how it works
The "test2" element is set to display as an inline-block, which means it displays inline with the text. This means that it can then be affected by properties that manipulate lines of text, such as "text-align".
Setting "text-align" to "center" on the "test1" element makes the inline content -- the "test2" element in this case -- within it become centered on the screen.
The standard way to center a block is to set the "margin-right" and "margin-left" properties to "auto", but that only works for elements that are displayed as blocks and that have a width that is less than 100%.
I would just put it in a div and float it next to another div with nothing in it.
http://www.barelyfitz.com/screencast/html-training/css/positioning/
Like in step 8 in this link.
The reason that it looks like the text "Sale!" is floated to the left is that <img> elements display as inline blocks by default, so the image is on the same line of text as the words "Sale!". A <br /> tag immediately following the text "Sale!" would solve that problem; but you said you can't modify this HTML, right?
Given that restriction, here is how I was able to solve the problem...
Surround the HTML from your example in a <span> tag and assign it a class. I used "test" as my class name".
Then Place this CSS in the head of the HTML document:
<style language="text/css">
/*<![CDATA[ */
.thumbnail img {
display: block;
}
.test {
display: inline-block;
}
.test .price, .test .below-thumb {
display: block;
text-align: center;
}
/* ]]> */
</style>
why it works
The selector for making the image display as a block solves the problem of the missing <br /> tag.
The span tag with which you surrounded the HTML displays as an inline block. This means that it will collapse around its contents, giving you a box within which you can center the text.
Making the items that contain the text display as a block causes them to take a width of 100%, filling the surrounding box
The inclusion of "text-align: center" is what finally makes the text display as centered within its container

CSS Space between 2 paragraphs not working

On my website on the page "Equipe", I would like some more space between the text "Founder and Managing Director" and the text below. I tried margin bottom but doesn't seem to work. Any suggestion?
Note: a br would be too much space.
HTML code:
<div class="equipe-bio">
<img src="images/avatar-man.png" width="80" height="80" alt="Picture" />
<p><span class="bioname">Gregory Yrogerg</span></p>
<p><span class="biotitle">Founder and managing director</span></p>
<p>Originaire de Belgique, Gregory vit depuis plus de 20 années en Norvège. Lorem ipsum dolor sit amet,...</p>
</div>
A simple fix would be to add the margin-bottom to the <p> tag, which should achieve your desired effect:
<p style="margin-bottom: 5px;">
<span class="biotitle">Founder and managing director</span>
</p>
By default span is an inline element. So if you wanted to add a margin to a span, you would have to change the display property:
.biotitle {
display: block;
margin-bottom: 5px;
}

Resources