HTML/CSS justifying text in separate blocks - html

Taking any page from any book or article that is justified and trying to make an exact online replica (same look and feel with HTML/CSS), that is including justifying the text with the exact line break and setting the outer wrapper with a width that match the min/max-width of the text itself - is this at all possible?
The HTML could be something like this:
...
<div class="page-wrapper">
<span class="line">The Republic of Plato is the longest of his works with the exception of the Laws,</span>
<span class="line">and is certainly the greatest of them. There are nearer approaches to modern</span>
<span class="line">metaphysics in the Philebus and in the Sophist; the Politicus or Statesman is</span>
<span class="line">more ideal; the form and institutions of the State are more clearly drawn out</span>
</div>
...
Note 1:
This CSS-trick isen't scalable as it relies on the rendering engine, and either the fix with (in example below set as 500px) will break either A) too early and add unwanted breaklines, B) too late and add large word-spacing or C) a case-by-case assessment that's of no good either as it's maybe perfect on the desktop but falls short on either A) or B) on mobile, vice versa.
.page-wrapper {
text-align: justify;
width: 500px;
}
.line:after {
content: "";
display: inline-block;
width: 100%;
}
Note 2:
I would prefer a pure HTML/CSS solution, if this is not possible, let's get JS on the table...

You could just use <p> paragraph with <br> break tags where necessary.
CSS wouldn't be complicated either
p {
text-align: justify;
}
Although I'm not necesarilly sure
What you're asking for
Why it has to be an exact replica of the source, since web is fairly dynamic.
C) a case-by-case assessment that's of no good either as it's maybe perfect on the desktop but falls short on either A) or B) on mobile, vice versa.
Seeing as you are also having problems with different sizes, #media queries might help quite a bit.
#media only screen and (max-width: 600px) {
// DO SOMETHING HERE IF SCREEN IS SMALLER THAN 600px
}
You could also have 2 different divs and hide one where necessary, and show the other.
div.mobile {
display: block;
}
div.desktop {
display: none;
}
#media only screen and (max-width: 600px) {
div.desktop {
display: block;
}
div.mobile{
display: none;
}
}

The quick and dirty way:
Work out you maximum character length. Use a monospaced font. Set your wrapper width using the ch unit and your max character count, eg 82ch. Next set a container with a max width of 100vw and overflow:auto so that the content is scrollable.
.page-container {
max-width:100vw;
overflow:auto;
}
.page-wrapper {
text-align: justify;
width: 82ch;
background-color:#EEE;
font-family:courier;
font-size:15px;
}
.line:after {
content: "";
display: inline-block;
width: 100%;
}
<div class="page-container">
<p class="page-wrapper">
<span class="line">The Republic of Plato is the longest of his works with the exception of the Laws,</span>
<span class="line">and is certainly the greatest of them. There are nearer approaches to modern</span>
<span class="line">metaphysics in the Philebus and in the Sophist; the Politicus or Statesman is</span>
<span class="line">more ideal; the form and institutions of the State are more clearly drawn out</span>
</p>
</div>
Slightly fancier:
Same as the above but set some media break points to adjust the font size. I'll leave it to you to work out font-sizes and break points.
.page-container {
max-width: 100vw;
overflow: auto;
}
.page-wrapper {
text-align: justify;
width: 82ch;
background-color: #EEE;
font-family: courier;
font-size: 15px;
}
.line:after {
content: "";
display: inline-block;
width: 100%;
}
#media screen and (max-width:768px) {
.page-wrapper {
background-color: #EFE;
font-size: 12px;
}
}
#media screen and (max-width:575px) {
.page-wrapper {
background-color: #FEE;
font-size: 11px;
}
}
<div class="page-container">
<p class="page-wrapper">
<span class="line">The Republic of Plato is the longest of his works with the exception of the Laws,</span>
<span class="line">and is certainly the greatest of them. There are nearer approaches to modern</span>
<span class="line">metaphysics in the Philebus and in the Sophist; the Politicus or Statesman is</span>
<span class="line">more ideal; the form and institutions of the State are more clearly drawn out</span>
</p>
</div>
What javascript can add
You could use javascript to calculate the max number of characters per line and update the with in ch based on the result.
Why not calculate font size based on width I hear someone ask? Well the problem with that is font size is based on character height, so basing it of width is... problematic.

Related

Flexbox: Two even columns - big image (with aspect-ratio) and content

I need to create an information section that includes an image and content next to it.
It should look like this:
I have already written a little bit of code, but it does not seem to be the best solution: everything works fine, but code is not graceful.
Please, have a look:
/* Simple reset */
img {
display: block;
max-width: 100%;
}
body {
background-color: black;
}
.information {
display: flex;
gap: clamp(5rem, 10vw, 8rem);
}
.information > * {
width: 50%; /* Using the 'width' property. */
}
.information-content {
align-self: center;
color: white;
}
.information-image {
align-self: flex-start;
object-fit: cover;
aspect-ratio: 1 / 1.10;
border-radius: 5px;
}
<section>
<div class="container">
<div class="information">
<img
class="information-image"
alt="Products for companies & Startups"
src="https://s3-alpha-sig.figma.com/img/6630/3672/40959a0086f9fbb8418c0829b277dd93?Expires=1670198400&Signature=gpQ5NqRXp9omRHkjCl718I9WPLqfx4xPKp1CQSMKbEnRCU7izmQIXkcn6zI6Z17p8Q7Li-wBAXb3P2Jg9qEuJauFeKqErbl4jgW950K35-LeX394hN7fJ7UEPmkgGSqB-drY1QdU7NZVV4QKTrZ0QBuw47xVBPOOfJMQO8NPOpZkx43UbbkS1yGgnxN5tELyriz9e8pH6pXO8AnJx7zvGz4mm3InyHOySUcb3ibVPa9XKJ8fyxPnkBeVoYFvwpiVddEs7uVNqCkCRuN2dJIIQg78FB-6TYX13nQ~NxvhG2059ks2q52a9p0N-DSmSYE-Yt-jedbJ1fEt3cZVnIfzUw__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA"
/>
<div class="information-content">
<h2>
My main goal is to keep my customers satisfied.
</h2>
<p>
Even with skills that are primarily mental, such as
computer programming or speaking a foreign language.
</p>
<p>
Even with skills that are primarily mental, such as
computer programming or speaking a foreign language.
</p>
</div>
</div>
</div>
</section>
My concern is the width property set on each child of my flex parent. As far as I know, using width inside flexbox is not the best idea? However, when I try to use the flex-basis property, everything breaks.
Note: I cannot use display: grid because the image can be after the content - with grid I will have to change the order and the code will become more complicated.

What happens when you have two media queries that are at the same size?

Lets you say you have two media queries on an element that both match. How do you know which one wins?
For example, let's say you have a media query that sets a rectangle to be red at LESS than or equal to 500 pixels and you a media query that makes it blue at MORE than or EQUAL to 500 pixels. Which one wins? And let's say you have a phone that is 500 pixels wide.
hr {
width: 400px;
left: 10px;
top: 0;
position: absolute;
}
.rect {
left: 10px;
position: absolute;
top: 20px;
right: 10px;
}
#media (max-width: 400px) {
.rect {
background-color: lightgray;
}
}
/* larger content */
#media (min-width: 400px) {
.rect {
background-color: lightblue;
}
}
<div class="rect">
Here is a div
</div>
<hr width="500px">
I would like to setup proper media break points. Do I need to rewrite them? Should they be min-width 501px and so on?
Normally it's the style declaration that comes last in the code that "wins" (is applied!). You can set !important on a style declaration, but IMHO that is toss-up and sometimes doesn't work. I 'think' id styles will have more importance over class styles, but I do know you can set multiple class name styles more influential.
Code not tested:
#less_important {
background : green;
width : 50px;
height : 50px;
}
.blue {
background : blue;
width : 50px;
height : 50px;
}
.red {
background : red;
border : 1px solid yellow;
}
<html>
<div id = "less_important" class = "blue">
</div>
<div class = "blue red">
</div>
<div class = "red blue">
</div>
</html>
Move the style .red and .blue in the code and see what happens to understand
CSS mean Cascading Style Sheets.
Definition of cascade:
"Something arranged or occurring in a series or in a succession of stages so that each stage derives from or acts upon the product of the preceding."
So, whatever comes after in the cascade will overwrite the previous.
Yes, you should set the one with min-width to 401.

change text on different size screen

So I am making a website using the mobile first method. now my question is: how can i change the text/images etc (not the font-size)?
so when you open the site on a phone it show a text for example: hello there and when your on a laptop/pc it show a different text like: have a nice day the same goes for images/buttons
I know the #media screen and (min-width) but how do I add this to the html without showing the text when not needed?
I have given two solutions.
#1 Solution: display: none / display: block
This is a fairly simple and common way to display content, depending on the screen size. And as I said above in the comments, you can operate on the display: none / display: block rule by setting two texts in the container.
Also, by turning off the visibility of the text for a mobile device, using the pseudo-class :nth-child():
.container p:nth-child(2) {
display: none;
}
And from to, the media query will turn the rules for each text:
#media (max-width: 767px) {...}
.container p {
font-size: 32px;
color: green;
}
.container p:nth-child(2) {
display: none;
}
#media (max-width: 767px) {
.container p:nth-child(1) {
display: none;
}
.container p:nth-child(2) {
display: block;
}
}
<div class="container">
<p>This is notebook</p>
<p>This is mobile</p>
</div>
#2 Solution: pseudo-class :after
This solution is less code, due to the absence of the need to specify the text in the tags. In this case, the text is passed as the content: '' parameter.
.container p {
font-size: 32px;
color: green;
}
.container p:after {
content: 'This is notebook';
}
#media (max-width: 767px) {
.container p:after {
content: 'This is mobile';
}
}
<div class="container">
<p></p>
</div>
Simply use JavaScript. For example, if you have this for mobile users:
<div class="mobile"><p>Hey, I'm on mobile!</p></div>
And this for PC users:
<div class="computer"><p>Hey, I'm on PC!</p></div>
Then you can do it like this:
<script>
const mobile = document.querySelector(".mobile"),
pc = document.querySelector(".computer"),
media = window.matchMedia("(max-width: 1000px)")
if (media.matches) {
mobile.style.display = "none"
pc.style.display = "block"
} else {
pc.style.display = "none"
mobile.style.display = "block"
}
</script>
You can use #media only screen and (hover: none). It's a media query that detects devices with hover ability. So you can write your original code for mobile first and then add your media query for devices that don't have hover abilities like desktops. It doesn't require to specify a screen width or anything like that since you can't predict every screen size out there. It automatically detects devices with hover or not for every screen size
Exmp:
#media only screen and (hover: none){
.mystyle{
// your style here
color: red
}
}
I think it's a good way without having the need to duplicate your code.

Media Query - Change <h1> content?

Im trying to create a responsive design here through media queries - so far it's been going pretty well, although i just hit a wall!
I have a h1 in my header which is pretty long, so when the screen gets small enough, it won't fit in - and ruins the responsive idea.
What i am asking is, is it possible to change the content in my h1 when the gets - lets say 500px wide? (example)
Right now my h1 is "CARSTEN ANDERSEN", and i would like it to change to "CARSTEN" at 500px.
Thanks in advance
<h1>Carsten <span class="hide-when-narrow">Andersen</span></h1>
<style>
#media (max-width: 500px) {
.hide-when-narrow {
display: none;
}
}
</style>
Since this is a question of content, it should be handled in the markup.
You could hide the excess words/letters by using max-width with overflow: hidden (use white-space: nowrap to force one line):
h1 { border:1px solid red; }
#media (max-width: 500px) {
h1 { max-width: 158px; overflow: hidden; white-space: nowrap; }
}
<h1>CARSTEN ANDERSEN</h1>
JSFiddle: https://jsfiddle.net/azizn/cs5ttm7s/
You need to change the content property
h1:before {
content: 'CARSTEN ANDERSEN';
}
#media only screen and (max-width: 500px) {
h1:before {
content: 'CARSTEN';
}
}
<h1>
</h1>
Something like this?

Responsive CSS- Different Layout for Different Size

So, I basically want to have 2 different layouts for a page on my website.
For under 400px:
[image]
description
[image]
description
For above 400px:
[image] description
[image] description
(so, the image and the text are on the same line)
I know I can do this very easily with Bootstrap if my breakpoint was one of the predefined ones, but it is not. So, what would the best approach be? Could I still use Bootstrap grid system and 'hack' it somehow or do something else altogether?
Thanks!
Here is a snippet
/*screen width over 400px*/
#media (min-width: 401px){
img {
width:50px;
height:50px;
}
p{
display:inline;
}
}
/*screen upto 400px*/
#media (max-width: 400px){
img {
width:100px;
height:100px;
}
}
<img src='https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcSSHCRPXAtpOWvSaR4T5ecblzIT-RdIV19VjNB4uUPPnEq_UT5r'>
<p id='p1'>
description
</p>
<img src='https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQEaoUONNbTby87bfUNcRrdufGcaLSbDnC3SGSqKLk1ZwNFMEE3'>
<p id='p2'>
description
</p>
Alright your going to have to use media queries. Here are a few examples that I wrote.
A media query is a set of styles(styles that you set)that has a certain screen size condition.
When this screen size condition is met the styles given inside the media query override any other styles that contradict the styles outside the media query.
Here is an example
#media (max-width: 500px) {
#visible {
display: none;
}
}
<p id="visible">Not Hidden</p>
<p>Change screen sizes!</p>
Here is the basic syntax of media queries
First make the #media then add a screen size condition (max-width: 1000px) or (min-width: 500px) heres an example using max-width. Then, add the styles inside the media query.(Dont forget to close the media query!)
#media (max-width: 1000px) {
h1 {
display: none;
}
#hidden {
display: block;
}
}
p {
display: none;
}
<h1 id="heading">Heading</h1>
<p id="hidden">Hidden</p>
Now run the code snippet above and you will see that the heading will appear when the screen size is above 1000px and it disappears and a hidden phrase appears when the screen size is below 1000px.
Here is a tutorial on media queries Media Queries
What you're looking for are css media queries. Check this page for an in-depth explanation http://www.w3schools.com/cssref/css3_pr_mediaquery.asp.
Alternatively, in your case it looks like you simply want to wrap the descriptions on to the next line when the viewport becomes too narrow. If this is the case then there's no need to add in extra markup because you can just leverage the natural behavior of inline-block elements. This link will clarify the behavior of inline-block elements for you http://www.w3schools.com/css/css_inline-block.asp.
I would go this way, using a row structure.
It will give you some more options down the road, when/if you maybe want 3 img/text lined up, or ... and so on, sooner or later maybe a header, maybe a footer.
.header {
padding: 10px;
border-bottom: 1px solid #999;
}
.container {
padding: 10px;
white-space: nowrap;
}
.container .row {
margin-bottom: 10px;
}
.container .row span {
margin-left: 10px;
}
.container .row.at-top span {
vertical-align: top;
}
#media (max-width: 400px){
.container .row span {
display: block;
margin-left: 0;
margin-top: 10px;
}
}
<div class="header">
<div class="row">
Header
</div>
</div>
<div class="container">
<div class="row at-top">
<img src="http://lorempixel.com/200/100/sports" />
<span> Some text ... being aligned at top</span>
</div>
<div class="row">
<img src="http://lorempixel.com/200/100/city" />
<span> Some text ... or at bottom</span>
</div>
</div>