In CSS, granular control over where word wrapping occurs? - css

TL;DR: Wondering if there's a CSS property that can break content where HTML doesn't naturally:
Baby
Buggy Bumpers
instead of
Baby Buggy
Bumpers
The only way I can think of to do it is to add where you don't want the line to break, but I'm working in WordPress, which strips those.
This is to graphically style a site's name on the home page. The site name is part of the nav, so it's inside an <li>, using grid layout.
Luckily in my case, setting the width with a dimension that is relative to the font size seems to break the way I want at all viewport widths:
.my-brand a {
width: 16ch;
text-align: end;
}
white-space: nowrap and such elements won't work with the "baby buggy bumpers" example because the need is to break after one specific word. Just wondering if there's some way to specify in a way similar to nth-child(2).
Made a Codepen to play with.

If you can't use Javascript and can't add tags in the string like :
<div class='string'>
Baby<span>Buggy Bumpers</span>
</div>
It only remain "hacky" CSS solution. There is one using pseudo-elements :
HTML :
<div class='string'>
Baby
</div>
CSS :
.string{
width: 11ch;
text-align: end;
font-size: 2em;
}
.string::after {
content: "Buggy Bumpers";
color: red;
display:block ;
white-space:nowrap;
}
Live exemple : https://codepen.io/camillewemajin/pen/JjWzWzN
But that's not really clean for many reasons, like SEO...

Related

h1 creates unwanted space above the text

I'm sure my question is quite a newbie one, anyway I can't figure out what I'm doing wrong. Basically, I created a <div> that I use as header, and inside of it another <div> that contains an image (logo) and a title (using <h1>).
The problem is that I get an unwanted extra space above the body
as you can see in this picture.
If I get rid of the <h1> title then everything is fine. I think the problem is due the float: left; property that I have assigned to the image, because if I assign no float property then the space disappears, but as you can see if I remove the float: left; the image and the title are not "aligned" anymore. So, the question is, how can I make the image to stay on the left and the title on the right of the image, without using float properties?
Any help will be appreciated, thanks!
Edit: Thanks everybody for the answers, I'm studying HTML and CSS at school and things like this are rarely mentioned by my teachers. Thanks again
A h1 element has margin by default. Simply remove it by adding:
margin: 0;
To the styles for your h1 element.
you can use this:
<h1 style="margin-top:0px; padding-top:0px">some text</h1>
At start of your work you should clear the style for margin (browser apply some of them).
So just in start of css file write:
h1 {
margin: 0;
}
A lot of devs just start a css file like :
* {
margin: 0;
padding: 0;
}
for clear it :)
Also you should read something about css reset and css normalize :)
This is because every browser has a default stylesheet, which you can find in Browsers' default CSS stylesheets. As you can see, the default margins are not zero. This can be solved by explicitly adding margin: 0px to your CSS.

Can and should you style custom elements

Usually when I create a custom element I wrap it in a section or other appropriate HTML element and style that, but this leads the DOM looking like custom-element > section.
My question is, is it wrong to remove the section and simply treat custom-element as the root element and style that?
For example I have a custom element called tabs, right now when it's used the DOM ends up looking like tabs > div.tabs but I'd prefer to remove the div.tabs element if there's nothing wrong with that.
So my question is is it "wrong" to style my custom elements and treat them as any other HTML element, or should I continue to ignore my custom elements completely (even though it's hard to do so when you use > and other selectors)?
There is absolutely nothing wrong with styling custom elements. To reassure you, custom elements are valid HTML and unless you're supporting an older browser less than Internet Explorer 9, then you'll need to do some extra work to get the browser to recognise them.
I style custom elements all of the time, I even style Aurelia's <router-view> custom element as well.
It's better...
Don't forget that the default CSS display for a custom element is inline.
So if you want to use border, width... you should explicitly set display (to inline-block for example):
custom-element {
background: lightgreen;
width: 60px;
border: 1px solid blue;
}
.ok {
display: inline-block;
}
<custom-element>This is
<div>ugly</div>
</custom-element>
<hr>
<custom-element class="ok">That's
<div>fine</div>
</custom-element>

How to change classes while object oriented css with bem?

Well I'm watching videos about oop css with bem. I didn't understand one thing. I have a media object and I use it everywhere like in navbar and content and footer etc. So how shall I change the media object and insiders. I guess 3 ways there are.
1 - I can catch inside other blocks grandchild chooser
it will like ".navbar .media".
This way makes me worrying because of grandchildren is making slow and complicated I think. Don't think about only .media. I have to select media-item etc etc...
2 - I can give another class to .media like .navbar together
it will like ".navbar.media".
This way need more classes to html so it makes me thinking.
3 - I guess there is no third option if there is please let me know :) Which way I shall do.
Thank you already.
You should add an extra class, navbar__media (that's a double underscore for descendant), and add that to the media elements inside of the navbar.
A rule of BEM/OOP CSS is that an element should always have their style defined by the classes they have, and not based on where they are in the DOM.
For reference: http://getbem.com/naming/
Example:
<div class="navbar">
<div class="media navbar__media"></div>
</div>
<div class="media"></div>
With this css:
.navbar {
background: #00f;
}
.media {
background: #f00;
}
.navbar__media {
background: #0f0;
}

How to do CSS text replacement using generated :before or :after without absolute positioning?

I'm attempting to allow our CMS editors the ability to swap out the text used for a page title using only a css override.
<header data-alternate="An Alternate Title">
This Page's Default Title
</header>
Using the :before or :after tag, one could use one of many available alternate titles.
header:before {
content: attr(data-alternate);
display: inline-block;
}
If only we could also say,
header:text {
display: none;
}
Unfortunately, as far as I can tell, there is no good way to hide "This Page's Default Title" in order to replace it with "An Alternate Title". If this were a Sprite, we could use one of the well-worn image replacement techniques like Phark or otherwise. Not so much with text replacement generated by :before, because the :before is also affected by the CSS devices used to hide the default text so that, with Phark, for example, the :before content is also at -9999px.
There are solutions I'm trying to avoid.
Using the Phark method or somesuch to hide the default text and then using absolute positioning on the :before content to put it back at left: 0, top: 0. I want/need to preserve flow if possible.
Wrapping the "Page's Default Title" in a span and just setting it to display: none in the CSS when an alternate title is being used.
i.e.
<header data-alternate="An Alternate Title">
<span class="default">This Page's Default Title</span>
</header>
This works, but a span nested in a header is displeasing.
Is there a way to target a tag's text without also targeting its generated :before/:after content? Is there another way to do this?
I'm not sure if this is exactly what you want, but you could try something like this:
p {
visibility: hidden;
}
p:before {
content: attr(data-alternate);
display: inline-block;
visibility: visible;
}
http://jsfiddle.net/yJKEZ/
You can set the visibility of the p element to be hidden, and then set the visibility of the :before pseudo-element to be visible within it's parent (the p) despite it's setting.
If that doesn't quite work as expected, there isn't really anything tremendously wrong with adding an extra span in, to help the process. It might not be as clean, but it could work better.
I do, however, want to raise the question of why you might need to do this, and point out some concerns with an approach like this...
For starters, pseudo elements are not part of the DOM, so that alternate text can't be selected, and isn't as accessible to the browser (or the user). Screen readers or search engines will see the default text, and not pay any attention to the alternate text, but that's what your user will see... This could lead to some confusion.
While your question specifies that you want to be able to do this with CSS, and while it may be possible, it really isn't the best solution for doing something like this. Especially if your website is being viewed in an older browser which does not support pseudo elements (Now the user sees nothing at all!).
I would more recommend something like this for swapping an image out for alt text in a print stylesheet, or swapping a hyperlink's text for the full address that it links too (again, mainly for a print stylesheet). Changing important content like a heading in this fashion can cause a lot of other issues, especially in terms of accessibility.
Just something for you to consider along with my answer... I hope I've helped you with your problem!

Display first letter only for glyph fonts (accessible way)

I have a glyph font and want to use it to achieve this effect:
My code so far:
<div class="ico linkedin">linkedin</div>
.ico {border-radius:10em; background:black; color:white}
.linkedin {visibility:hidden;}
.linkedin:first-letter {
font-family:'JustVector';
font-size:900%;
text-indent:1em;
visibility:visible
}
This does the trick in Chrome, but not in Firefox or Internet Explorer 9. Also, this isn't accessible, because JAWS doesn't read the hidden or display:none elements.
So, I tried something like:
.linkedin {position:absolute; left:-5em}
.linkedin:first-letter {/*etc*/ position:absolute; left:6em}
But it doesn't work. Is there a proper and accessible way to achieve this?
The accessible way to use icons is to use img elements with adequate alt attributes, e.g.
<img src=smiley.gif alt="Just joking!">
Icon fonts (which is what you probably mean by “gliph font”) have inherent accessibility problems. Using e.g. letters and trying to fool browsers into rendering them as icons with CSS means that with CSS turned off, there are just the letters, which are wrong information. Using elements with empty content and CSS-generated content suffers from the same problem, except that instead of wrong information, there is no information, when CSS (or at least the visual part of CSS) is off.
I don't think there is a truly accessible way of using icon fonts currently. I know it's a bit span-tastic but this what my approach to this would be.
Firstly wrap the text in a span so we can hide it. And add another span for the icon
<div class="ico">
<span aria-hidden="true" class="linkedin"></span>
<span class="hide">linkedin</span>
</div>
Notice I've added aria-hidden="true" to my icon span. This is to prevent the letter (used to render the icon) from being read out by the screen reader.
Now you can safely hide the text so it is accessible by screen readers and apply your icon using the before selector.
.linkedin:before {
font-family: 'JustVector';
content: 'l';
}
.hide{
position: absolute;
top: -9999px;
left: -9999px;
}
Thanks for the answers, they present me a few questions about how to deal with this.
Well, finally I go with the easy one. I think it's accesible and more semantic, also works if there's no CSS in the page, also it's possible to be printed.
I have separated the first letter (the icon) with a margin of surrounding text, and I left the layer with overflow:hidden;. Then, have adjusted margin and line-height, to focus well the character/icon inside the circle.
The final code:
.ico {background:black; border-radius:10em; height:5em; overflow:hidden; position:relative; width:5em; color:white;}
.linkedin:first-letter {font-family:'JustVector'; font-size:400%; line-height: 1.3em; margin-left:0.2em; margin-right:1em;}
With that solution, screenreaders reads "linkedin" and it only display the icon for other users giving them enough information.

Resources