Align wrapping text correctly using CSS - html

This might be a totally silly question. Here is my problem - I have a message box displayed in HTML (using Bootstrap) to show various user alerts. It has an information icon (using bootstrap glyphicons) and associated message. Everything looks fine unless the message is too long. Then the second line will wrap under the icon. I want the multiple lines to wrap starting where the first line starts.
So this would be wrong:
(i) This is an incorrect
format of the message
And this would be right:
(i) This is the correct
format I want
My HTML/CSS is very simple:
<div class='alert alert-info'>
<span class='glyphicon glyphicon-information'></span>
&nbsp my message comes here.
</div>
But I looked at couple of sites including css-tricks and all the solutions seemed really complicated. So I am posting here to see if there is a quick and easy way to do this.

You can play with CSS positioning, what you need to do is, push the entire element to the left using margin-left: 30px; and than, assign position: relative; to the container element so that we make sure that the absolute positioned element doesn't flow out in the wild.
Now we use position: absolute; for your glyph icon and use negative left value and a positive top value to set the icon correct, please tweak these values according to your requirements, rest stays the same
.alert {
margin-left: 30px;
width: 50px;
position: relative;
}
.alert .glyphicon {
position: absolute;
left: -15px;
top: 2px;
}
Demo

what about wrapping your message inside it's own span and styling it to have a margin-left of 15px or whatever width the information icon is? are you unable to do that? if so, you can set the style on the
.alert .alert-info {
margin-left:15px;
}
and subsequently set the margin on the span to 0
div .glyphicon glypicon-information{
margin: 0;
}

Related

Cannot figure out z index issue, trying to place graphic text over image that is positioned to the bottom right of section

I am trying to avoid using position absolute for my mobile-first, responsive website./ I am having a tough time getting the h1 and p tag in front of the image. With position absolute comes more troubles down the road, so I would like to avoid that. Also any advice for dealing with those svg lines or should I remove them? Here's my code:
.climate {
padding: 2em 1em 5rem;
}
.reverse {
font-size: 2.5rem;
font-weight: var(--fw-normal);
color: var(--clr-light);
z-index: 10;
}
.disaster-graphic {
background-color: var(--clr-background);
}
.graphic-image {
z-index: 1;
margin: -150px 0 0 205px;
padding: 0;
}
.greenroof {
max-width: 600px;
}
<section class="climate disaster-graphic">
<h2 class="reverse">Reverse the climate disaster</h2>
<p class="orange">Learn what it takes to bring your business to the next level.</p>
<div class="graphic-image">
<img src="/images/greene 1.png" class="greenroof">
</div>
z-index can be tricky. Unfortunately, when working with z-index you have to at least position the element of which you are trying to move along the z-axis. Some helpful reading about z-index:
4 reasons your z-index isn't working (and how to fix it)
To solve your problem, you can simply add position: relative to your .graphic-image. Furthermore, change it's z-index from 1 to -1. Lastly, you do not need to have a z-index: 10 on .reverse. On elements where z-index is not specified, it is set to auto (0). So in this case -1 < 0.
I used a placeholder image and also changed the color of your text just so you can see it in front of the image.
Regarding your "SVG lines", you'll have to post some more code to get further assistance with that issue.
body{
color: goldenrod; /* to be removed, just so you can see the text in front of image */
}
.climate {
padding: 2em 1em 5rem;
}
.reverse {
font-size: 2.5rem;
font-weight: var(--fw-normal);
color: var(--clr-light);
/*remove z-index: 10 */
}
.disaster-graphic {
background-color: var(--clr-background);
}
.graphic-image {
z-index: -1; /*change z-index to -1*/
margin: -150px 0 0 205px;
padding: 0;
position: relative; /*add position*/
}
.greenroof {
max-width: 600px;
}
<section class="climate disaster-graphic">
<h2 class="reverse">Reverse the climate disaster</h2>
<p class="orange">Learn what it takes to bring your business to the next level.</p>
<div class="graphic-image">
<!-- placeholder image -->
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/800px-Image_created_with_a_mobile_phone.png" class="greenroof">
</div>
z-index only sets the z-order of a positioned element or a flex item. That is to say z-index does nothing unless either you specify the position of the element or the element is a flex item. In your case neither of those are true so z-index does nothing.
The easiest solution is to simply add position: relative to .reverse and .orange.
I've quickly put together a working codepen for context.
Regarding the svg lines, there are many ways you could deal with them but it depends what your goal is. I am going to assume you always want them "attached" to the orange box like in the image you've shared but don't want their existence to impact the layout of the rest of the elements.
That being the case, I would suggest using position: absolute on the svg with the svg element being a direct child of .orange (which you will have now added position:relative to solve your z-index issue). This will "attach" the svg to the orange box so that wherever the orange box goes, the green lines go too. It would be helpful to see more of your code so that part of your question could be answered in more detail.
Personally I would have made the orange box an element and placed the <p> tag inside it rather than styling the <p> to look like text inside and orange box. You may have had a reason for doing it your way though. The codepen I added above contains my solution for the svg lines by the way.

How to make this span which contains a svg be next to a div

codepen.io/f0rta/pen/qBXRXvV
First of all, I'm sorry for the HTML being a little bit of a mess, my project is developed in React, that's why.
So, I'd like to have the audio icon next to the first test div. However, I'm not able to do it, I don't know why, even if I set fa-stack-custom to display: inline-block.
I expected setting my span to inline-block to make it stay next to the first test div, but it doesn't. (I think that's because of the SVGs)
How can I make it stay next to the first test div?
First of all, I'm sorry for the HTML being a little bit of a mess, my project is developed in React, that's why.
So, I'd like to have the audio icon next to the first test div. However, I'm not able to do it, I don't know why, even if I set fa-stack-custom to display: inline-block.
I expected setting my span to inline-block to make it stay next to the first test div, but it doesn't. (I think that's because of the SVGs)
How can I make it stay next to the first test div?
Link to the changed code since stackoverflow doesn't allow characters greater than 5000.
There are several changes which I made and some of them are these:
.fa-w-16{
margin-left:50px;
}
.svg-inline--fa{
vertical-align: -1em;
display: inline;
}
.fa-stack-2x{
position: relative;
}
.fa-w-18.fa-stack-1x {
margin-left: -1.8em;
margin-bottom: 0.5em;
}
.question {
display: inline-block;
border: 1px solid black;
border-radius: 1.5rem;
width: 75%;
text-align: left;
margin: 0.1rem 0;
height: 2.5rem;
margin-right: 5em;
}
.svg-inline--fa.fa-circle.circle-audio {
top: 15;
}
.fa-w-18.fa-stack-1x {
top: 15;
}
These changes might not be the same exactly. The circle and the SVG are lined in front of the first test box(I think that is what you wanted.) As long as it stays there no matter what the viewport size the circle will contain the SVG but things get tricky when you try to move the circle along with the SVG. Apparently, you have to move them one by one. I was only able to make sense of it this much.
Make the width for both of the elements' parent 'max-width', and then set display for the svg and text box to inline.

Can't set data-icon alignment and padding

I downloaded a symbol from Fontastic and I've added it in my html with
SHOW MORE NEWS <span aria-hidden="true" data-icon="a"></span>
The problem is the symbol is 18px x 20px. It adds unwanted space in the <a> element, and I can't add padding or align it with the text.
How can I do it?
The easiest way would probably be to position your icon absolute, so it gets lifted out of the flow and doesn't affect the parent a anymore. Something like this should do the trick:
[data-icon="a"] {
position: absolute;
left: 100%;
bottom: 0;
}
a {
position: relative;
}
You may want to use some different selectors, but you get the idea...
I've set up a small fiddle to demonstrate: https://jsfiddle.net/1wsuc7ns/
update:
You commented that you only see part of the symbol. That is somewhat strange since the above code should not affect the size of the symbol in any way. Perhaps there is some other css at play here. The first thing that comes to mind is an overflow:hidden; on the a. Give the following code a try:
[data-icon="a"] {
position: absolute;
right: 0;
bottom: 0;
}
a {
position: relative;
padding-right: 20px;
}
So I added some extra space for the icon inside the a tag (you may have to play with the number a bit) and changed the positioning to keep the symbol inside the a.
Another problem could be that there is something covering up the symbol. You could try adding a reasonably high z-index to the symbol to see if that solves it.
Not much more I can tell without looking at the actual rendered page...

Fixed placement of element, but considering pseudo before element

I have an annoying issue with the html layout of a form. I cannot really change the general setup, since it is part of a huge framework. But I have to "move" a button to a more suitable location. I am close, but not happy with the solution so far. Maybe you can give me some idea in this. Here is a dramatically simplified version to demonstrate my approach:
I have two container divs, top and bottom.
The top container shows a button on the left side. That button is fixed, but can have a different width due to the translation of its label.
The bottom container holds lots of stuff. Amongst that a second button at its top which works fine, but looks wrong. I want to optically move it into the top container, since there is a logical connection to the button in there. Sure, really placing it in there would be the correct solution, but I currently cannot do that. Instead I use a fixed position which works fine, except for the horizontal placement. I have to decide how far pushed from the left to place the button, so that it certainly does not overlap the first button in the container. I obviously have to consider all translations, the result works, but depending on the first buttons label I have an annoying horizontal gap between the two buttons.
I tried to use a pseudo element (::before) on the second button to help with the layout. Since when rendering the view I obviously have the translated label of the first button I can copy that into some property of the second button and use that property in my css to fill a before pseudo element of the second button which has exactly the same length as the first button. That is what is shown in the code example posted below.
What I completely fail to do is to place that pseudo element such that is it left in the top container (so exactly below the first button). The idea is to indirectly place the second button that way. Looks like this is not possible, obviously. But since I am a bloody beginner in markup and styling I thought it might be worth asking here...
Below is some drastically stripped down code to demonstrate my approach.
I create a jsfiddle for you to play around with. Here is the code:
HTML:
<div id="top-container">
<button>multilingual button text</button>
</div>
<div id="bottom-container">
<h2>
Some title opening the bottom container
<span class="into-top-container">
<button id="place-me" reference-text="multilingual button text">button to be placed</button>
</span>
</h2>
<p>Some content</p>
<p>Some content</p>
<p>Some content</p>
</div>
CSS:
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
div {
margin: 0;
padding: 5px;
}
button {
margin: 0;
padding: 5px;
white-space: nowrap;
}
div#top-container {
width: 100%;
border: 1px solid green;
}
div#bottom-container {
width: 100%;
border: 1px solid blue;
}
#place-me {
position: fixed;
top: 0;
left: 400px;
margin: 5px;
background: yellow;
}
#place-me::before {
z-index: 0;
/*visibility: hidden;*/
position: absolute;
content: attr(reference-text);
margin: 0 5px;
padding: 0;
background: gold;
right: 100%;
}
Notes:
that in the above code the second button is placed with left: 400px;. That is more or less what I want to change. But obviously left: 0 is not correct...
the visibility css rule for the pseudo element is currently commented out for demonstration purpose
keep in mind that the second button is *not* contained inside the top container, but actually logically below the title of the bottom container. The goal is to move it optically up into the top container which already is where close to what I want. Except for the horizontal alignment...
Upon request here is a screenshot:
It is taken from the fiddle I posted above. I added the red ellipse which shows what element pair I want to move and the left pointing arrow indicating where I want to move that too. I want to move it exactly that far, that the two tests "multilingual button text" are exactly placed on top of each other, but without specifying an explicit left placement obviously. That is why the pseudo element exists: as a dummy placeholder. I would then hide that pseudo element and have the second button placed exactly right of the first button, regardless of how long the translated text in there is.
So the final result should like like that:
OK, I invested some more time, since this issue popped up again after a regression in our code and I found, as often after allowing some time to pass, a logical and relatively clean solution:
I use the same stripped down code to for demonstration purposes.
The jsfiddle is based on the one provided in the question itself.
HTML: no real change, except for the reference-text having moved from button to container, for the why see below:
CSS:
* {
font-size: 12px;
font-weight: normal;
font-family: Arial;
}
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-size: 12px;
font-weight: normal;
}
span,
div {
margin: 0;
padding: 5px;
}
button {
margin: 0;
padding: 5px;
white-space: nowrap;
}
div#top-container {
width: 100%;
border: 1px solid green;
}
div#bottom-container {
width: 100%;
border: 1px solid blue;
}
span.into-top-container {
position: fixed;
top: 0;
left: 0;
pointer-events: none;
border: 1px solid transparent;
}
span.into-top-container::before {
visibility: hidden;
content: attr(reference-text);
position: relative;
margin-right: 5px;
padding: 5px;
border: 2px solid;
background: gold;
}
#place-me {
background: yellow;
pointer-events: all;
}
The basic change in strategy: it is the container holding the button to be placed that has to be positioned in a fixed manner, not that button itself (so the <span class="into-top-container">)! That allows to use the pseudo before element, now also anchored to that container, not the button, to take the space as required without actually getting part of the button itself.
Since that container is now place over the original multilingual button that one is not clickable any more. That issue is fixed by a css pointer-events set to none for the container and set to all for the placed button again. That makes the container itself simply ignore all events (clicks) and have them passed to the original button beneath.
I had to make sure that the font used inside the pseudo element is style exactly like the original multilingual button. That actually makes sense, since the font styling defines the actual width used by that button, so the actual width used by the pseudo element should be defined in exactly the same manner. In the example above I forced that by simply setting all elements font style rules to some fixed values (the initial * {...} in the CSS code). That can obviously also be done right inside the css rules for the pseudo element itself. I chose the more simple and brute variant here to keep the code clean.

How can I style a part of a single character with overlays using a dynamic width?

Question
Can I style just a part of a single character?
Meaning
CSS attributes cannot be assigned to parts of characters. But if you want to style only a certain section of a character, there is no standardized way to do that.
Example
Is it possible to style an "X" which is half-way red and then black?
Not working code
<div class="content">
X
</div>
.content {
position: relative;
font-size: 50px;
color: black;
}
.content:after {
content: 'X';
color: red;
width: 50%;
position: absolute;
overflow: hidden;
}
Demo on jsFiddle
Purpose
My intention is styling the Font Awesome icon-star symbol. If I have an overlay with dynamic width, shouldn't it be possible to create an exact visualization of scores?
While playing around with a demo fiddle, i figured it out myself and wanted to share my solution. It's quite simple.
First things first: The DEMO
To partly style a single character, you need extra markup for your content. Basically, you need to duplicate it:
<​div class="content">
<span class="overlay">X</span>
X
</div>
Using pseudo-elements like :after or :before would be nicer, but i didn't found a way to do that.
The overlay needs to be positioned absolutely to the content element:
​.content {
display: inline-block;
position: relative;
color: black;
}
​.overlay {
width: 50%;
position: absolute;
color: red;
overflow: hidden;
}​
Do not forget overflow: hidden; in order to cut off the remaing part of the "X".
You can use any width instead of 50% which makes this approach very flexible. You can even use a custom height, other CSS attributes or a combination of multiple attributes.
Extended DEMO
Great work on your solution. I’ve got a version that uses :after (instead of duplicating the content in the HTML) working in Chrome 19.
http://jsfiddle.net/v5xzJ/4/
Basically:
Set position:relative on .content
Position :after absolutely
Set :after to overflow:hidden
Adjust the width, height, text-indent and line-height of :after to hide bits of it.
I’m not sure if it’ll work well cross-browser though — the em values will probably work out a bit differently. (Obviously it definitely won’t work in IE 7 or below.)
In addition, you end up having to duplicate the content in your CSS file instead of the HTML, which might not be optimal depending on the situation.