I need help in fixing a 2-column list.
The problem is that the right column intrudes into the left one if more than single line used.
Another trouble is that if left column has more than one line, the content inside of the right column will appear at the bottom.
The separating line between columns also acts strange with more than 1 line (see the examples below).
Please note, I'd like to keep "Title" and "Description" columns in separate HTML-tags (at least one of them inside a tag), because I need this for Responsive CSS layout.
ul {
list-style: none!important;
}
ul.my-list>li {
width: 550px!important;
position: relative;
padding-left: 30px;
padding-right: 15px;
background: 0 0;
border-radius: 0!important;
margin: 0;
box-sizing: border-box;
background: #EEE;
}
ul.my-list>li span {
width: 140px;
border-right: 1px solid #E0E0E0;
display: inline-block;
padding: 3px 0;
line-height: 38px;
margin-right: 15px;
}
<ul class="my-list">
<li><span>Title</span>Description. Not too many words – displays well.</li>
</ul>
<br>
<br>
<ul class="my-list">
<li><span>Title</span>Description. More words – this goes wrong. Really wrong. Seriously...At least the "Description" column should not intrude into the "Title" column.</li>
</ul>
<br>
<br>
<ul class="my-list">
<li><span>Title with many words acts weird too</span>Description. How to fix the "Description" column, so it would start from the top side, not from the bottom?</li>
</ul>
<br>
<br>
try this
ul.my-list>li span {
float:left;
}
ul.my-list>li {
min-height: 80px;
}
I've solved the problem, mostly by creating two separated <span> tags for each of the columns and using display: inline-flex; for the whole <li> tag.
The solution is CSS Responsive Layout friendly and works with all window sizes.
JSFiddle: http://jsfiddle.net/tay06de4/4/
Related
The problem
I recently discovered an encoding problem in my backend for when calculating the initials of a user when the first letter is germanic letter (e.g Ö and Ä). Those letters couldn't be parsed and ended up being a question-mark.
But what I also discovered is a rather peculiar behavior (and the reason I seek advise) in my markup that simply makes no sense to me whatsoever.
I've replicated simplified example below:
ul {
padding: 0;
display: flex;
}
li {
list-style-type: none;
font-family: 'Roboto', sans-serif;
flex-direction: column;
margin: 15px;
width: 260px;
min-height: 200px;
padding: 30px 15px;
text-align: center;
background: white;
border: 1px solid #E8E8E8;
}
.avatar {
height: 35px;
width: 35px;
border: 2px solid #333;
line-height: 35px;
padding: 1px 2px;
align-self: auto;
margin: 10px auto 0;
position: relative;
}
.avatar span {
left: 50%;
position: absolute;
transform: translateX(-50%);
}
<ul>
<li>
<div class="avatar">
<span>?N</span>
</div>
<h4>Örjan Norberg</h4>
<span>orjan#example.com</span>
</li>
<li>
<div class="avatar">
<span>II</span>
</div>
<h4>Isaac Ibarra</h4>
<span>isaac#example.com</span>
</li>
<li>
<div class="avatar">
<span>WW</span>
</div>
<h4>Wyatt Williams</h4>
<span>wyatt#example.com</span>
</li>
</ul>
You'll see that "Örjans" initials are ?N, but also that the "N" is being pushed down to the next line. This doesn't seem to be related to the avatar width because I tried with both long and short initials.
In fact, even if I put WWWWW or something else (pic) that overflows the avatar, there is no line-break which is as expected. I also tried other special characters, such as & and %, but those behave just as any other character or letter.
Question
What causes this behavior when using the question-mark specifically? Is it somehow related to the font (Roboto) or is it my css?
Also, (see pics below) how come this happens when the question-mark is followed by a letter, but not when the order is reversed (letter first) or when followed by another question-mark?
What's going on here??
EDIT 1: Using OSX/Chrome.v59, though can replicate in Windows7/IE11
EDIT 2: Apparently the — character also causes this behavior (thanks to #MrLister for finding this)
What you see happening is that the bounding client rectangle for the combination ?N is too wide to fit without overflow, and so the browser does whatever it should do when it sees overflow, based on default rules and CSS overrides. Part of the reason is that the translate and scale transforms do not reposition elements, they only draw them somewhere else, so your transform does not counteract your absolute positioning. Have a look at http://jsbin.com/gujafokiwe/edit?html,css,output and notice that as far as the DOM is concerned that span is still in its original position, we've only told CSS to draw it somewhere else.
When the browser sees ?N (and specifically: some browsers. Not all of them) it might see that it needs to break the line based on the bounding client rect dimensions. However, browsers are free to pick their rules for when and how to break text sequences (CSS does not specify which rules must be used, only that for unicode content outside of CJK it is advisable to use http://www.unicode.org/reports/tr14/tr14-37.html) and while your example works fine in my Firefox, not breaking the text at all, my Chrome does see overflow, and does try to break up the sequence(s) as best as it knows how to.
Unfortunately, the only true answer on why it does that is in the code for the text render engine - that's either in Blink, or in Webkit, both of which are (mostly) open source and so unless you happen to get the eyes of the person or people who implemented it on this question, you're going to have to seek them out rather than hope they browser Stackoverflow and find your question: your best bet is to read through http://www.chromium.org/blink#participating and then post this question to their dev mailing list.
(Solutions for your problem are varied: remove the .avatar span rule and just text-align: center the parent div, or even better: use flexbox rules)
The ? in the first span is a word-break opportunity; after all, the N is the start of a word. This doesn't happen in the other spans, since those contain a whole word each only. So what you should do is apply white-space: nowrap to the span, so that it no longer wraps.
Edit: while this is not the explanation to what's actually happening - it doesn't happen with most other non-word characters, so "word boundary" is not the whole of the story; see comments - it still provides a practical workaround, so I'm leaving this up.
ul {
padding: 0;
display: flex;
}
li {
list-style-type: none;
font-family: 'Roboto', sans-serif;
flex-direction: column;
margin: 15px;
width: 260px;
min-height: 200px;
padding: 30px 15px;
text-align: center;
background: white;
border: 1px solid #E8E8E8;
}
.avatar {
height: 35px;
width: 35px;
border: 2px solid #333;
line-height: 35px;
padding: 1px 2px;
align-self: auto;
margin: 10px auto 0;
position: relative;
}
.avatar span {
left: 50%;
position: absolute;
transform: translateX(-50%);
white-space:nowrap;
}
<ul>
<li>
<div class="avatar">
<span>?N</span>
</div>
<h4>Örjan Norberg</h4>
<span>orjan#example.com</span>
</li>
<li>
<div class="avatar">
<span>II</span>
</div>
<h4>Isaac Ibarra</h4>
<span>isaac#example.com</span>
</li>
<li>
<div class="avatar">
<span>WW</span>
</div>
<h4>Wyatt Williams</h4>
<span>wyatt#example.com</span>
</li>
</ul>
I have some text and want it to be higher and inline with the first icon. This is it live: http://www.penguinie.co.uk/#projects the css is:
.german img {
height: 100;
width: 100;
padding: 2px 2px 1px 2px;
}
.german img:hover {
border: 1px solid #2e8ece;
border-radius: 10px 10px 10px 10px;
}
.german-content {
display: none;
float: right;
width: 400px;
}
.german:hover .german-content {
display: inline-block;
border: 1px solid;
}
.german-content p {
font-size: 15px;
font-weight: normal;
line-height: 30px;
word-spacing: 5px;
color: black;
}
.chembond img {
height: 100;
width: 100;
padding: 2px 2px 1px 2px;
}
.chembond img:hover {
border: 1px solid #2e8ece;
border-radius: 10px 10px 10px 10px;
}
.chembond-content {
display: none;
float: right;
width: 400px;
}
.chembond:hover .chembond-content {
display: inline-block;
border: 1px solid;
}
.chembond-content p {
font-size: 15px;
font-weight: normal;
line-height: 30px;
word-spacing: 5px;
color: black;
overflow: scroll;
}
And this is the HTML:
<section id="projects-content">
<p>Projects</p>
<section class="german">
<img src="assets/img/german.png" height="60" width="50" />
<section class="german-content">
<p>I started this project because I have seen many students in my German class keep on getting the tenses wrong by putting verbs in the wrong places, missunderstanding past participles etc... so I started this to help students (or anyone) understand the sometimes confusing German tenses. Each tense page consistes of three sub-sections: a question, an answer and a statement. These then in turn include an example and an explanation. If you were to hover over some of the words then a popup box will appear, explaining the use of the word. You can see it here (please bare in mind that this is still a work in progress). If you want to email me a tip about it, or just ask me about it then don't hesitate to contact me.</p>
</section>
</section>
<section class="chembond">
<img src="assets/img/bonding.png" height="60" width="50" />
<section class="chembond-content">
<p>This isn't much of a project, more homework. In Science we were asked to create a poster on the different types of bonding (ionic, metallic, covalent, etc) and I naturally said no as I cannot draw and hate making posters. I then did it as homework and made a website. It was a joint website with my friend Elliott who did all the drawings/images, I then wrote the code. If you are wondering if my teacher like it then I can tell you that he did. If you want to see it then click here. I know there is one mistake in the image but I have put a note at the bottom of that section.</p>
</section>
</section>
</section>
So when I hover over the second icon I want the text in the box to be the same height as the first one is when you hover over it.
Here is what you should add to your css:
.chembond-content {
display: none;
float: right;
width: 400px;
position: relative;
top: -72px;
}
You could add margin-top with a negative value to your CSS, but NO.
A much more maintainable solution would be to have only one <section class="content"> tag, align it, and with JS change the text when hovering over the relevant icon.
when making a question here with simple CSS and HTML consider doing a jsFiddle and sharing that instead of a personal link, otherwise when this is working and your live link changes then the question will be irrelevant.
The CSS Position Approach
So here is my fiddle minus a bit of code clutter:
Demo
The reason the second image is hovered to reveal the the section element with the class of .chembond-content and the element is not at the top (like the first image) is because you are floating it to the right but it's still part of the document flow after that image that you have right before the section.
If you want to have both elements open up in the same spot then you would get them out of the document flow by giving them a fixed or absolute position which in this example I simple set it to 20 pixels from the top and from the right.
Since these elements are not taking up space in the flow of your markup then you are free to position both at the top if you want to.
I have five links all next to each other, and although they are set at 20% width, the last one goes onto the next line. However, when I set it to be 19.5%, it's fine. I made sure I set the padding and margin for body, the links, and all the containing elements to 0. Although it's not a major problem, any information on this would be appreciated.
Here is the html:
<div id="top">
<img src="someimage" />
<nav id="nav">
LINK1
LINK2
LINK3
LINK4
LINK5
</nav>
</div>
And the css:
body {
background-color: white;
margin: 0;
padding: 0;
}
#top {
background-color: #AAAAAA;
height: 50px;
}
#nav > a {
display:inline-block;
height: 25px;
width: 19.5%;
background-color: #AAAAAA;
margin: 0;
padding: 0;
text-align: center;
text-decoration: none;
color: #222222;
}
Thanks for the answers. I put comments between the tags, and it works.
It's the white space in between the tags. Check out this article for things you can do to combat it.
My suggestion is to simply put the HTML all on one line. It's harder to read, but renders what you want.
The best way, though, is to have a build step that will minify your HTML and get rid of all of it automatically.
inline-block has a problem of translating the line breaks into spaces, which might break your layout, i'd suggest you use floats instead:
#nav{
overflow:hidden;
}
#nav > a {
float: left;
height: 25px;
width: 19.5%;
background-color: #AAAAAA;
margin: 0;
padding: 0;
text-align: center;
text-decoration: none;
color: #222222;
}
The newline between each link translates to a space. This is the width that is being added.
You can either write all <a> tags on one line, make them float or add comments between them, like so:
<nav id="nav">
LINK1<!--
-->LINK2<!--
-->LINK3<!--
-->LINK4<!--
-->LINK5
</nav>
Following simple list, where in every h4, there is a span at the end.
<ul class="items">
<li>
<h4>Prevent LineBreakOfPlus <span class="goto">o</span>
</h4>
</li>
<li>
<h4>Digital Signage <span class="goto">o</span></h4>
…
</ul>
Screenshot of the page's source:
The CSS for the span looks like this …
.items .goto {
font-family: 'QuaySans-Icons';
font-size: 1.6em;
position: relative;
float: right;
}
The final thing looks like this:
The problem I have with this is that when decreasing the width of the browser window (I'm working on a responsive webdesign) the span-icon is breaking into the next line.
Do you have any creative solution or idea on how to prevent this from happening?
Kind regards and thank you in advance,
Matt
If you want the icon to keep inline with the last word in your text line, you can simply do:
<ul class="items">
<li>
<h4>Prevent LineBreakOfPlus<span class="goto">o</span></h4>
</li>
<li>
<h4>Digital Signage<span class="goto">o</span></h4>
</li>
</ul>
and the CSS might be:
.items {
list-style: none;
margin: 0;
padding: 0;
}
.items li {
border-bottom: 1px solid gray;
margin: 0;
padding: 0;
}
.items h4 {
margin: 0;
}
.items .goto {
background-color: gray;
font-size: 1.6em;
margin-left: 10px; /* optional */
}
If there is no white space between your work and the span, the motif will simply follow the word if the li element is forced to flow into a second line.
You can use margin-left to create visual spacing or insert a   entity before the span, quite a few ways to do. The details depend a bit on what effect you want.
Fiddle: http://jsfiddle.net/audetwebdesign/VsBet/ (two examples of how to do it)
Keeping Icon Right Justified
Here is one approach to pinning the icon to the right of the h4 element:
.ex2.items h4 {
position: relative;
line-height: 1.5;
outline: 1px dotted blue;
padding-right: 2.00em;
}
.ex2.items .goto {
background-color: wheat;
line-height: 1.00;
font-size: 1.6em;
position: absolute;
right: 0;
bottom: 0.0em;
height: 1.00em;
width: 1.00em;
outline: 1px dotted red;
}
Use absolute positioning of the span to keep it to the right and bottom of h4. If h4 forms to line, the icon will follow the second line. You may need to adjust the positioning depending on the icon size. If you allow the icon to grow in size, you may get other issue in extreme cases. I might fix the icon to a px height or width (or a max value). Finally, set some padding-right in h4 to prevent the icon from overlapping the text as the window gets smaller.
Note I explicitly specified line-height values to accentuate the issue around not knowing the height of the icon. You may need to adjust these to vertically position the icon.
Decrease your font-size when you have less space. I guess you have the problem in media with max-width:480px. I found decreasing the font-size a good alternative to keep the design consistent in responsive sites
I've mocked it up on the demo, however it is a bit raw.
.items {
padding:0;
margin:0;
/*width:180px;*/
}
.items li {
border: 1px solid red;
list-style-type: none;
position: relative;
}
.items h4 {
margin:0; padding:0; font-size:16px; padding-right:10px;
}
.items .goto {
margin-top: -10px;
position: absolute;
right: 0;
top: 50%;
}
DEMO
Check the following link and decrease the width of browser.
RESULT
I have an unordered list of items, I want to display each item as a box with two lines of text inside, each line with different properties (font, size, text-align...). The markup I am using for each item looks like this:
<li id="1">
<p class="first"><!-- First line of text --></p>
<p class="last"><!-- Second line of text --></p>
</li>
Using CSS I want it to display sort of like this:
My questions are:
I know this can be achieved in various ways with CSS, but what is the right way or best practice to do it for best cross-browser support? can you point me to a CSS example for something similar? the first text label should be 2 px from the top border and the second one 2 px from the bottom.
Is this the right markup for the text labels? or should I be using other tags instead of <p>? maybe <div>?
I am using display: block for the <li> tags, with fixed width and height.
Thanks in advance.
If I understand correctly, this should be good:
Live Demo
Tested in IE7/IE8 and recent versions of: Firefox, Chrome, Safari, Opera.
I also tested in IE6, works there to.
I'm only doing all this testing because you specifically asked for the "best cross-browser support" :)
I might be tempted to change the <p> tags for <span> tags, because these don't really seem to be paragraphs of text.
CSS:
ul {
list-style: none;
font-size: 200%;
line-height: 0.8
}
li {
display: block;
width: 140px;
height: 100px;
background: #ccc;
padding: 2px;
border: 1px solid #000;
position: relative;
margin: 8px 0
}
li .last {
position: absolute;
bottom: 2px;
right: 2px
}
HTML:
<ul>
<li id="l1">
<p class="first">Text 1</p>
<p class="last">Text 2</p>
</li>
<li id="l2">
<p class="first">Text 1</p>
<p class="last">Text 2</p>
</li>
</ul>
You might be able to use a selector like this:
#1 p + p { padding-right: ..px }
Which if I know anything at all about CSS should get the adjacent sibling of the p element in #1
Here is how I would do it:
li
{
display: block;
padding: 2px;
height: xxpx; /* The height that you gave the li */
width: xxpx; /* The width that you gave the li */
}
li p
{
height: xxpx;
}
li p.first
{
float: left;
}
li p.second
{
float: right;
/*
To place the 2nd text at the bottom right corner you need to give it a
margin top
The value of this margin should be the total height of the li tag minus the
height of text (p tag) and minus the total vertical padding that is 4px.
*/
margin-top: xxpx;
}
I guess that will do it. Hope it helps.