Chapter 1: Birth | CSS-Tricks

Chapter 1: Birth | CSS-Tricks

Tim Berners-Lee is fascinated with information. It has been his life’s work. For over four decades, he has sought to understand how it is mapped and stored and transmitted. How it passes from person to person. How the seeds of information become the roots of dramatic change. It is so fundamental to the work that he has done that when he wrote the proposal for what would eventually become the World Wide Web, he called it “Information Management, a Proposal.”

Information is the web’s core function. A series of bytes stream across the world and at the end of it is knowledge. The mechanism for this transfer — what we know as the web — was created by the intersection of two things. The first is the Internet, the technology that makes it all possible. The second is hypertext, the concept that grounds its use. They were brought together by Tim Berners-Lee. And when he was done he did something truly spectacular. He gave it away to everyone to use for free.

When Berners-Lee submitted “Information Management, a Proposal” to his superiors, they returned it with a comment on the top that read simply:

Vague, but exciting…

The web wasn’t a sure thing. Without the hindsight of today it looked far too simple to be effective. In other words, it was a hard sell. Berners-Lee was proficient at many things, but he was never a great salesman. He loved his idea for the web. But he had to convince everybody else to love it too.

Tim Berners-Lee has a mind that races. He has been known — based on interviews and public appearances — to jump from one idea to the next. He is almost always several steps ahead of what he is saying, which is often quite profound. Until recently, he only gave a rare interview here and there, and masked his greatest achievements with humility and a wry British wit.

What is immediately apparent is that Tim Berners-Lee is curious. Curious about everything. It has led him to explore some truly revolutionary ideas before they became truly revolutionary. But it also means that his focus is typically split. It makes it hard for him to hold on to things in his memory. “I’m certainly terrible at names and faces,” he once said in an interview. His original fascination with the elements for the web came from a very personal need to organize his own thoughts and connect them together, disparate and unconnected as they are. It is not at all unusual that when he reached for a metaphor for that organization, he came up with a web.

As a young boy, his curiosity was encouraged. His parents, Conway Berners-Lee and Mary Lee Woods, were mathematicians. They worked on the Ferranti Mark I, the world’s first commercially available computer, in the 1950s. They fondly speak of Berners-Lee as a child, taking things apart, experimenting with amateur engineering projects. There was nothing that he didn’t seek to understand further. Electronics — and computers specifically — were particularly enchanting.

Berners-Lee sometimes tells the story of a conversation he had with his with father as a young boy about the limitations of computers making associations between information that was not intrinsically linked. “The idea stayed with me that computers could be much more powerful,” Berners-Lee recalls, “if they could be programmed to link otherwise unconnected information. In an extreme view, the world can been seen as only connections.” He didn’t know it yet, but Berners-Lee had stumbled upon the idea of hypertext at a very early age. It would be several years before he would come back to it.

History is filled with attempts to organize knowledge. An oft-cited example is the Library of Alexandria, a fabled library of Ancient Greece that was thought to have had tens of thousands of meticulously organized texts.

Photo via

At the turn of the century, Paul Otlet tried something similar in Belgium. His project was called the Répertoire Bibliographique Universel (Universal Bibliography). Otlet and a team of researchers created a library of over 15 million index cards, each with a discrete and small piece of information in topics ranging from science to geography. Otlet devised a sophisticated numbering system that allowed him to link one index card to another. He fielded requests from researchers around the world via mail or telegram, and Otlet’s researchers could follow a trail of linked index cards to find an answer. Once properly linked, information becomes infinitely more useful.

A sudden surge of scientific research in the wake of World War II prompted Vanneaver Bush to propose another idea. In his groundbreaking essay in The Atlantic in 1945 entitled “As We May Think,” Bush imagined a mechanical library called a Memex. Like Otlet’s Universal Bibliography, the Memex stored bits of information. But instead of index cards, everything was stored on compact microfilm. Through the process of what he called “associative indexing,” users of the Memex could follow trails of related information through an intricate web of links.

The list of attempts goes on. But it was Ted Neslon who finally gave the concept a name in 1968, two decades after Bush’s article in The Atlantic. He called it hypertext.

Hypertext is, essentially, linked text. Nelson observed that in the real world, we often give meaning to the connections between concepts; it helps us grasp their importance and remember them for later. The proximity of a Post-It to your computer, the orientation of ingredients in your refrigerator, the order of books on your bookshelf. Invisible though they may seem, each of these signifiers hold meaning, whether consciously or subconsciously, and they are only fully realized when taking a step back. Hypertext was a way to bring those same kinds of meaningful connections to the digital world.

Nelson’s primary contribution to hypertext is a number of influential theories and a decades-long project still in progress known as Xanadu. Much like the web, Xanadau uses the power of a network to create a global system of links and pages. However, Xanadu puts a far greater emphasis on the ability to trace text to its original author for monetization and attribution purposes. This distinction, known as transculsion, has been a near impossible technological problem to solve.

Nelson’s interest in hypertext stems from the same issue with memory and recall as Berners-Lee. He refers to it is as his hummingbird mind. Nelson finds it hard to hold on to associations he creates in the real world. Hypertext offers a way for him to map associations digitally, so that he can call on them later. Berners-Lee and Nelson met for the first time a couple of years after the web was invented. They exchanged ideas and philosophies, and Berners-Lee was able to thank Nelson for his influential thinking. At the end of the meeting, Berners-Lee asked if he could take a picture. Nelson, in turn, asked for a short video recording. Each was commemorating the moment they knew they would eventually forget. And each turned to technology for a solution.

By the mid-80s, on the wave of innovation in personal computing, there were several hypertext applications out in the wild. The hypertext community — a dedicated group of software engineers that believed in the promise of hypertext – created programs for researchers, academics, and even off-the-shelf personal computers. Every research lab worth their weight in salt had a hypertext project. Together they built entirely new paradigms into their software, processes and concepts that feel wonderfully familiar today but were completely outside the realm of possibilities just a few years earlier.

At Brown University, the very place where Ted Nelson was studying when he coined the term hypertext, Norman Meyrowitz, Nancy Garrett, and Karen Catlin were the first to breathe life into the hyperlink, which was introduced in their program Intermedia. At Symbolics, Janet Walker was toying with the idea of saving links for later, a kind of speed dial for the digital world – something she was calling a bookmark. At the University of Maryland, Ben Schneiderman sought to compile and link the world’s largest source of information with his Interactive Encyclopedia System.

Dame Wendy Hall, at the University of Southhampton, sought to extend the life of the link further in her own program, Microcosm. Each link made by the user was stored in a linkbase, a database apart from the main text specifically designed to store metadata about connections. In Microcosm, links could never die, never rot away. If their connection was severed they could point elsewhere since links weren’t directly tied to text. You could even write a bit of text alongside links, expanding a bit on why the link was important, or add to a document separate layers of links, one, for instance, a tailored set of carefully curated references for experts on a given topic, the other a more laid back set of links for the casual audience.

There were mailing lists and conferences and an entire community that was small, friendly, fiercely competitive and locked in an arms race to find the next big thing. It was impossible not to get swept up in the fervor. Hypertext enabled a new way to store actual, tangible knowledge; with every innovation the digital world became more intricate and expansive and all-encompassing.

Then came the heavy hitters. Under a shroud of mystery, researchers and programmers at the legendary Xerox PARC were building NoteCards. Apple caught wind of the idea and found it so compelling that they shipped their own hypertext application called Hypercard, bundled right into the Mac operating system. If you were a late Apple II user, you likely have fond memories of Hypercard, an interface that allowed you to create a card, and quickly link it to another. Cards could be anything, a recipe maybe, or the prototype of a latest project. And, one by one, you could link those cards up, visually and with no friction, until you had a digital reflection of your ideas.

Towards the end of the 80s, it was clear that hypertext had a bright future. In just a few short years, the software had advanced in leaps and bounds.

After a brief stint studying physics at The Queen’s College, Oxford, Tim Berners-Lee returned to his first love: computers. He eventually found a short-term, six-month contract at the particle physics lab Conseil Européen pour la Recherche Nucléaire (European Council for Nuclear Research), or simply, CERN.

CERN is responsible for a long line of particle physics breakthroughs. Most recently, they built the Large Hadron Collider, which led to the confirmation of the Higgs Boson particle, a.k.a. the “God particle.”

CERN doesn’t operate like most research labs. Its internal staff makes up only a small percentage of the people that use the lab. Any research team from around the world can come and use the CERN facilities, provided that they are able to prove their research fits within the stated goals of the institution. A majority of CERN occupants are from these research teams. CERN is a dynamic, sprawling campus of researchers, ferrying from location to location on bicycles or mine-carts, working on the secrets of the universe. Each team is expected to bring their own equipment and expertise. That includes computers.

Berners-Lee was hired to assist with software on an earlier version of the particle accelerator called the Proton Synchrotron. When he arrived, he was blown away by the amount of pure, unfiltered information that flowed through CERN. It was nearly impossible to keep track of it all and equally impossible to find what you were looking for. Berners-Lee wanted to capture that information and organize it.

His mind flashed back to that conversation with his father all those years ago. What if it were possible to create a computer program that allowed you to make random associations between bits of information? What if you could, in other words, link one thing to another? He began working on a software project on the side for himself. Years later, that would be the same way he built the web. He called this project ENQUIRE, named for a Victorian handbook he had read as a child.

Using a simple prompt, ENQUIRE users could create a block of info, something like Otlet’s index cards all those years ago. And just like the Universal Bibliography, ENQUIRE allowed you to link one block to another. Tools were bundled in to make it easier to zoom back and see the connections between the links. For Berners-Lee this filled a simple need: it replaced the part of his memory that made it impossible for him to remember names and faces with a digital tool.

Compared to the software being actively developed at the University of Southampton or at Xerox or Apple, ENQUIRE was unsophisticated. It lacked a visual interface, and its format was rudimentary. A program like Hypercard supported rich-media and advanced two-way connections. But ENQUIRE was only Berners-Lee’s first experiment with hypertext. He would drop the project when his contract was up at CERN.

Berners-Lee would go and work for himself for several years before returning to CERN. By the time he came back, there would be something much more interesting for him to experiment with. Just around the corner was the Internet.

Packet switching is the single most important invention in the history of the Internet. It is how messages are transmitted over a globally decentralized network. It was discovered almost simultaneously in the late-60s by two different computer scientists, Donald Davies and Paul Baran. Both were interested in the way in which it made networks resilient.

Traditional telecommunications at the time were managed by what is known as circuit switching. With circuit switching, a direct connection is open between the sender and receiver, and the message is sent in its entirety between the two. That connection needs to be persistent and each channel can only carry a single message at a time. That line stays open for the duration of a message and everything is run through a centralized switch. 

If you’re searching for an example of circuit switching, you don’t have to look far. That’s how telephones work (or used to, at least). If you’ve ever seen an old film (or even a TV show like Mad Men) where an operator pulls a plug out of a wall and plugs it back in to connect a telephone call, that’s circuit switching (though that was all eventually automated). Circuit switching works because everything is sent over the wire all at once and through a centralized switch. That’s what the operators are connecting.

Packet switching works differently. Messages are divided into smaller bits, or packets, and sent over the wire a little at a time. They can be sent in any order because each packet has just enough information to know where in the order it belongs. Packets are sent through until the message is complete, and then re-assembled on the other side. There are a few advantages to a packet-switched network. Multiple messages can be sent at the same time over the same connection, split up into little packets. And crucially, the network doesn’t need centralization. Each node in the network can pass around packets to any other node without a central routing system. This made it ideal in a situation that requires extreme adaptability, like in the fallout of an atomic war, Paul Baran’s original reason for devising the concept.

When Davies began shopping around his idea for packet switching to the telecommunications industry, he was shown the door. “I went along to Siemens once and talked to them, and they actually used the words, they accused me of technical — they were really saying that I was being impertinent by suggesting anything like packet switching. I can’t remember the exact words, but it amounted to that, that I was challenging the whole of their authority.” Traditional telephone companies were not at all interested in packet switching. But ARPA was.

ARPA, later known as DARPA, was a research agency embedded in the United States Department of Defense. It was created in the throes of the Cold War — a reaction to the launch of the Sputnik satellite by Russia — but without a core focus. (It was created at the same time as NASA, so launching things into space was already taken.) To adapt to their situation, ARPA recruited research teams from colleges around the country. They acted as a coordinator and mediator between several active university research projects with a military focus.

ARPA’s organization had one surprising and crucial side effect. It was comprised mostly of professors and graduate students who were working at its partner universities. The general attitude was that as long as you could prove some sort of modest relation to a military application, you could pitch your project for funding. As a result, ARPA was filled with lots of ambitious and free-thinking individuals working inside of a buttoned-up government agency, with little oversight, coming up with the craziest and most world-changing ideas they could. “We expected that a professional crew would show up eventually to take over the problems we were dealing with,” recalls Bob Kahn, an ARPA programmer critical to the invention of the Internet. The “professionals” never showed up.

One of those professors was Leonard Kleinrock at UCLA. He was involved in the first stages of ARPANET, the network that would eventually become the Internet. His job was to help implement the most controversial part of the project, the still theoretical concept known as packet switching, which enabled a decentralized and efficient design for the ARPANET network. It is likely that the Internet would not have taken shape without it. Once packet switching was implemented, everything came together quickly. By the early 1980s, it was simply called the Internet. By the end of the 1980s, the Internet went commercial and global, including a node at CERN.

Once packet switching was implemented, everything came together quickly. By the early 1980s, it was simply called the Internet.

The first applications of the Internet are still in use today. FTP, used for transferring files over the network, was one of the first things built. Email is another one. It had been around for a couple of decades on a closed system already. When the Internet began to spread, email became networked and infinitely more useful.

Other projects were aimed at making the Internet more accessible. They had names like Archie, Gopher, and WAIS, and have largely been forgotten. They were united by a common goal of bringing some order to the chaos of a decentralized system. WAIS and Archie did so by indexing the documents put on the Internet to make them searchable and findable by users. Gopher did so with a structured, hierarchical system. 

Kleinrock was there when the first message was ever sent over the Internet. He was supervising that part of the project, and even then, he knew what a revolutionary moment it was. However, he is quick to note that not everybody shared that feeling in the beginning. He recalls the sentiment held by the titans of the telecommunications industry like the Bell Telephone Company. “They said, ‘Little boy, go away,’ so we went away.” Most felt that the project would go nowhere, nothing more than a technological fad.

In other words, no one was paying much attention to what was going on and no one saw the Internet as much of a threat. So when that group of professors and graduate students tried to convince their higher-ups to let the whole thing be free — to let anyone implement the protocols of the Internet without a need for licenses or license fees — they didn’t get much pushback. The Internet slipped into public use and only the true technocratic dreamers of the late 20th century could have predicted what would happen next.

Berners-Lee returned to CERN in a fellowship position in 1984. It was four years after he had left. A lot had changed. CERN had developed their own network, known as CERNET, but by 1989, they arrived and hooked up to the new, internationally standard Internet. “In 1989, I thought,” he recalls, “look, it would be so much easier if everybody asking me questions all the time could just read my database, and it would be so much nicer if I could find out what these guys are doing by just jumping into a similar database of information for them.” Put another way, he wanted to share his own homepage, and get a link to everyone else’s.

What he needed was a way for researchers to share these “databases” without having to think much about how it all works. His way in with management was operating systems. CERN’s research teams all bring their own equipment, including computers, and there’s no way to guarantee they’re all running the same OS. Interoperability between operating systems is a difficult problem by design — generally speaking — the goal of an OS is to lock you in. Among its many other uses, a globally networked hypertext system like the web was a wonderful way for researchers to share notes between computers using different operating systems.

However, Berners-Lee had a bit of trouble explaining his idea. He’s never exactly been concise. By 1989, when he wrote “Information Management, a Proposal,” Berners-Lee already had worldwide ambitions. The document is thousands of words, filled with diagrams and charts. It jumps energetically from one idea to the next without fully explaining what’s just been said. Much of what would eventually become the web was included in the document, but it was just too big of an idea. It was met with a lukewarm response — that “Vague, but exciting” comment scrawled across the top.

A year later, in May of 1990, at the encouragement of his boss Mike Sendall (the author of that comment), Beners-Lee circulated the proposal again. This time it was enough to buy him a bit of time internally to work on it. He got lucky. Sendall understood his ambition and aptitude. He wouldn’t always get that kind of chance. The web needed to be marketed internally as an invaluable tool. CERN needed to need it. Taking complex ideas and boiling them down to their most salient, marketable points, however, was not Berners-Lee’s strength. For that, he was going to need a partner. He found one in Robert Cailliau.

Cailliau was a CERN veteran. By 1989, he’d worked there as a programmer for over 15 years. He’d embedded himself in the company culture, proving a useful resource helping teams organize their informational toolset and knowledge-sharing systems. He had helped several teams at CERN do exactly the kind of thing Berners-Lee was proposing, though at a smaller scale.

Temperamentally, Cailliau was about as different from Berners-Lee as you could get. He was hyper-organized and fastidious. He knew how to sell things internally, and he had made plenty of political inroads at CERN. What he shared with Berners-Lee was an almost insatiable curiosity. During his time as a nurse in the Belgian military, he got fidgety. “When there was slack at work, rather than sit in the infirmary twiddling my thumbs, I went and got myself some time on the computer there.” He ended up as a programmer in the military, working on war games and computerized models. He couldn’t help but look for the next big thing.

In the late 80s, Cailliau had a strong interest in hypertext. He was taking a look at Apple’s Hypercard as a potential internal documentation system at CERN when he caught wind of Berners-Lee’s proposal. He immediately recognized its potential.

Working alongside Berners-Lee, Cailliau pieced together a new proposal. Something more concise, more understandable, and more marketable. While Berners-Lee began putting together the technologies that would ultimately become the web, Cailliau began trying to sell the idea to interested parties inside of CERN.

The web, in all of its modern uses and ubiquity can be difficult to define as just one thing — we have the web on our refrigerators now. In the beginning, however, the web was made up of only a few essential features.

There was the web server, a computer wired to the Internet that can transmit documents and media (webpages) to other computers. Webpages are served via HTTP, a protocol designed by Berners-Lee in the earliest iterations of the web. HTTP is a layer on top of the Internet, and was designed to make things as simple, and resilient, as possible. HTTP is so simple that it forgets a request as soon as it has made it. It has no memory of the webpages its served in the past. The only thing HTTP is concerned with is the request it’s currently making. That makes it magnificently easy to use.

These webpages are sent to browsers, the software that you’re using to read this article. Browsers can read documents handed to them by server because they understand HTML, another early invention of Tim Berners-Lee. HTML is a markup language, it allows programmers to give meaning to their documents so that they can be understood. The “H” in HTML stands for Hypertext. Like HTTP, HTML — all of the building blocks programmers can use to structure a document — wasn’t all that complex, especially when compared to other hypertext applications at the time. HTML comes from a long line of other, similar markup languages, but Berners-Lee expanded it to include the link, in the form of an anchor tag. The <a> tag is the most important piece of HTML because it serves the web’s greatest function: to link together information.

The hyperlink was made possible by the Universal Resource Identifier (URI) later renamed to the Uniform Resource Indicator after the IETF found the word “universal” a bit too substantial. But for Berners-Lee, that was exactly the point. “Its universality is essential: the fact that a hypertext link can point to anything, be it personal, local or global, be it draft or highly polished,” he wrote in his personal history of the web. Of all the original technologies that made up the web, Berners-Lee — and several others — have noted that the URL was the most important.

By Christmas of 1990, Tim Berners-Lee had all of that built. A full prototype of the web was ready to go.

Cailliau, meanwhile, had had a bit of success trying to sell the idea to his bosses. He had hoped that his revised proposal would give him a team and some time. Instead he got six months and a single staff member, intern Nicola Pellow. Pellow was new to CERN, on placement for her mathematics degree. But her work on the Line Mode Browser, which enabled people from around the world using any operating system to browse the web, proved a crucial element in the web’s early success. Berners-Lee’s work, combined with the Line Mode Browser, became the web’s first set of tools. It was ready to show to the world.

When the team at CERN submitted a paper on the World Wide Web to the San Antonio Hypertext Conference in 1991, it was soundly rejected. They went anyway, and set up a table with a computer to demo it to conference attendees. One attendee remarked:

They have chutzpah calling that the World Wide Web!

The highlight of the web is that it was not at all sophisticated. Its use of hypertext was elementary, allowing for only simplistic text based links. And without two-way links, pretty much a given in hypertext applications, links could go dead at any minute. There was no linkbase, or sophisticated metadata assigned to links. There was just the anchor tag. The protocols that ran on top of the Internet were similarly basic. HTTP only allowed for a handful of actions, and alternatives like Gopher or WAIS offered far more options for advanced connections through the Internet network.

It was hard to explain, difficult to demo, and had overly lofty ambition. It was created by a man who didn’t have much interest in marketing his ideas. Even the name was somewhat absurd. “WWW” is one of only a handful of acronyms that actually takes longer to say than the full “World Wide Web.”

We know how this story ends. The web won. It’s used by billions of people and runs through everything we do. It is among the most remarkable technological achievements of the 20th century.

It had a few advantages, of course. It was instantly global and widely accessible thanks to the Internet. And the URL — and its uniqueness — is one of the more clever concepts to come from networked computing.

But if you want to truly understand why the web succeeded we have to come back to information. One of Berners-Lee’s deepest held beliefs is that information is incredibly powerful, and that it deserves to be free. He believed that the Web could deliver on that promise. For it to do that, the web would need to spread.

Berners-Lee looked to his successors for inspiration: the Internet. The Internet succeeded, in part, because they gave it away to everyone. After considering several licensing options, he lobbied CERN to release the web unlicensed to the general public. CERN, an organization far more interested in particle physics breakthroughs than hypertext, agreed. In 1993, the web officially entered the public domain.

And that was the turning point. They didn’t know it then, but that was the moment the web succeeded. When Berners-Lee was able to make globally available information truly free.

In an interview some years ago, Berners-Lee recalled how it was that the web came to be.

I had the idea for it. I defined how it would work. But it was actually created by people.

That may sound like humility from one of the world’s great thinkers — and it is that a little — but it is also the truth. The web was Berners-Lee’s gift to the world. He gave it to us, and we made it what it was. He and his team fought hard at CERN to make that happen.

Berners-Lee knew that with the resources available to him he would never be able to spread the web sufficiently outside of the hallways of CERN. Instead, he packaged up all the code that was needed to build a browser into a library called libwww and posted it to a Usenet group. That was enough for some people to get interested in browsers. But before browsers would be useful, you needed something to browse.

Enjoy learning about web history with stories just like this? Jay is telling the full story of the web, with new stories every 2 weeks. Sign up for his newsletter to catch up on the latest… of what’s past.

Source link

When to Use Go vs. Java | One Programmer’s Take on Two Top L...

When to Use Go vs. Java | One Programmer’s Take on Two Top L…

Go vs. Java

I can honestly say I have enjoyed working with Java for quite some time now. I built up my expertise in software development working with backend technologies like EJB2, DB2, and Oracle over the last years at Spiral Scout. Over the years, I moved towards natural language processing-based bots including Spring Boot, Redis, RabbitMQ, Open NLP, IBM Watson, and UIMA. For years, my language of choice was Java and that has worked effectively, even being enjoyable to use at times.

Testing Out Go to Start

In early 2017, I took over a very interesting project that revolved around programming automated systems for monitoring and growing hydroponic plants. The original code base for the software incorporated Go gateways for three different systems — Windows, MacOS, and ARM.

Completely new to Go, my job quickly evolved into a mix of both learning and simultaneously implementing this new language as the project progressed. The challenge was daunting, especially because of the convoluted structure of the existing code base. Supporting a program with platform-specific parts written in CGo for three different operating systems essentially meant deploying, testing, and running maintenance for three different systems. In addition, the code was written with a singleton design pattern making the systems heavily interdependent, often unpredictable, and rather difficult to understand. In the end, I opted to engineer a new version of the gateway with a more Java-esque approach and that too ended up being rather ugly and confounding.

When I moved to Spiral Scout, where I currently serve as a tech lead for one of our biggest U.S. clients, I stopped trying to tap into my Java wheelhouse when developing with Go. Instead, I decided to embrace the language by developing in the most possible Go way and having fun with it. I found it to be an innovative and comprehensive language and our team still uses it daily for a variety of projects.

Like with any programming language, however, Go has its weak points and disadvantages, and I won’t lie, there are times where I really miss Java.

If my experience with programming has taught me anything, it’s that there is no silver bullet when it comes to software development. I’ll detail below how one traditional language and one new kid on the block worked in my experience.

Go vs. Java: The Similarities

Go and Java are both C-family languages which means they share a similar language syntax. That’s why Java developers often find reading Go code fairly easy and vice versa. Go does not use a semicolon (‘;’) symbol at the end of a statement though except in occasional cases where it is needed. To me, the line-delimited statements of Go feel clearer and more readable.

Go and Java also both use one of my favorite features, garbage collector (GC), to help prevent memory leaks. Unlike C++, C-family programmers have to worry about memory leaks and garbage collector is one of those features that automates memory management and therefore simplifies their job.

Go’s GC does not use the Weak Generational Hypothesis, however, it still performs very well and has a very short Stop-the-World (STW) pause. With version 1.5, the STW was reduced even more and essentially became constant, and with version 1.8, it dropped to less than 1ms.

Go’s GC only has a few settings though, i.e. the sole GOGC variable which sets the initial garbage collection target percentage. In Java, you have 4 different garbage collectors and tons of settings for each.

While Java and Go are both considered cross-platform, Java needs the Java Virtual Machine (JVM) to interpret compiled code. Go simply compiles the code into a binary file for any given platform. I actually consider Java less platform-dependent than Go because Go requires you to create a binary file every time you compile code for a single platform. Compiling binaries for different platforms separately is quite time-consuming from a testing and DevOps point of view and cross-platform Go compilation does not work in certain cases, especially when we use CGo parts. Meanwhile, with Java, you can use the same jar anywhere you have the JVM. Go requires less RAM and no additional considerations regarding installing and managing the virtual machine.

Reflection. Unlike Java where reflection is convenient, popular, and commonly used, Go’s reflection seems more complicated and less obvious. Java is an object-oriented language so everything except the primitive is considered an object. If you want to use reflection, you can create a class for the object and get the desired information from the class, like this:

This gives you access to constructors, methods, and properties so that you can invoke or set them.

In Go there is no notion of class and a structure contains only the declared fields. So we need to have the package “reflection” in order to provide the desired information:


I realize this isn’t a huge problem, but since there are no constructors for the structures in Go, the result is many primitive types that have to be processed separately as well as pointers that have to be taken into account. In Go, we can also pass something by pointer or value. The Go structure can have a function as a field, not a method. All this makes the reflection in Go more complex and less usable.

Accessibility. Java has private, protected and public modifiers in order to provide the scopes with different access for the data, methods, and objects. Go has exported/unexported identifiers that is similar to public and private modifiers in Java. There are no modifiers. Anything that starts with an uppercase letter is exported and will be visible in other packages. Unexported — lowercase variables or functions will only be visible from the current package.

Go vs. Java: The Big Differences

Golang is not an OOP language. At its core, Go lacks the inheritance of Java because it does not implement traditional polymorphism by inheritance. In fact, it has no objects, only structures. It can simulate some object-oriented patterns by providing interfaces and implementing the interfaces for structures. Also, you can embed structures to each other but embedded structures do not have any access to the hosting structure’s data and methods. Go uses composition instead of inheritance in order to combine some desired behavior and data.

Go is an imperative language and Java tends to be a declarative language. In Go, we don’t have anything like dependency injection; instead, we have to wrap up everything together explicitly. That’s why the recommended approach to programming in Go is to use as little magic as possible. Everything should be really obvious for an external code reviewer and a programmer should understand all the mechanisms for how the Go code uses the memory, file system, and other resources.

Java, on the other hand, requires more of a developer’s attention toward custom-writing the business logic portion of a program to determine how data is created, filtered, changed, and stored. As far as the system infrastructure and database management are concerned — all that is done by configuration and annotations via generic frameworks like Spring Boot. We concern ourselves less with the boring droll of repeating infrastructure parts and leave that to the framework. This is convenient but also inverts control and limits our ability to optimize the overall process.

The order of the variable’s definition. In Java you can write something like:

. . . but in Go you would write:

This was obviously confusing when I first started working with Go.

The Pros of Using Go

Simple and elegant concurrency. Go has a powerful model of concurrency called “communicating sequential processes” or CSP. Go uses an n-to-m profiler which allows m concurrent executions to happen in n system threads. The concurrent routine can be started in a very basic way simply using the keywords of the language, the same as the language’s name. For example, a coder can write the string:

. . . and the function doMyWork() will start executing concurrently.

The communication between the processes can be done with the shared memory (not recommended) and channels. It allows for very robust and fluid parallelism that uses as many cores of the processes as we define with the GOMAXPROCS environment variable.
By default, the number of processes is equal to the number of cores.

Go provides a special mode to run binary with a check for run race situations. This way you can test and prove that your software is concurrency safe.

This will run the application in run race detection mode.

I really appreciate that Go provides very useful, basic functionality right out-of-the-box ( One go-to example of this is the synchronization “sync” package for concurrency. For “Once” group type singleton implementations you can write:

Package sync also provides a structure for concurrent map implementation, mutexes, condition variables, and wait groups. Package “atomic” additionally allows for concurrency safe conversion and math operations — essentially everything we need for making a concurrency ready code.

Pointers. With pointers, Go allows for more control over how to allocate memory, garbage collector payload, and other interesting performance tweaks that are impossible with Java. Go feels like a more low-level language than Java and favors much easier and faster performance optimizations.

Duck typing. “If it walks like a duck and it quacks like a duck, then it must be a duck.” This saying holds true with Go: there is no need to define that a certain structure implements a given interface. If the structure has the methods with the same signatures in a given interface then it implements it. This is very helpful. As the client of a library, you can define any interfaces you need for external libraries structures. In Java, an Object has to explicitly declare that it implements the interface.

The profiler. Go’s profiling tools make analyzing performance issues convenient, quick and easy. The profiler in Go helps reveal the memory allocations and CPU usage for all parts of a program and can illustrate them in a visual graph making it extremely easy to take action around optimizing performance. Java also has many profilers, starting from Java VisualVM, but they are not as simple as the Go profiler. Their efficacy instead depends on the work of the JVM so the statistics obtained from them correlates with the work of the garbage collector.

CGO. Go allows for a very simple yet powerful integration of C so you are able to write platform-dependent applications with snippets of C code inside of your Go project. Essentially, CGo enables developers to create Go packages that call C code. There are various builder options in order to exclude/include C code snippet for a given platform which allows for multi-platform realizations of applications.

Function as an argument. A Go function may be used as a variable, passed into another function, or serve as a field of a structure. This versatility is refreshing. Starting from 1.8 version of Java, it incorporates the use of lambdas, they are not really functions, but one-function objects. While this facilitates a behavior similar to using functions in Go, the idea existed in Go from the very beginning.

Clear guidelines for the code style. The community behind Go is supportive and passionate. There is a ton of information out there about the best Go-way to do things with examples and explanations

Functions can return many arguments. This is also quite useful and nice.

The Cons of Using Go

No polymorphism except with interfaces. There is no ad-hoc polymorphism in Go which means if you have two functions in the same package with different arguments but the same sense, then you will have to give them different names. For example, with this code . . .

… you wind up with many methods doing the same thing but all with different and ugly names.

Additionally, there is no polymorphism by inheritance. If you embed a structure then the embedded structure knows only its own methods, it does not know the methods of the “hosting” structure. This is particularly challenging for developers like me who transitioned to Go after working mostly with an OOP language where one of the most basic concepts is inheritance.

But, over time I started to realize that this approach to polymorphism is just another way of thinking and makes sense because, in the end, the composition is more reliable, evident, and run time is changeable.

Errors handling. It is completely up to you what errors are returned and how they are returned, so as the developer, you need to return the error every time and pass it up accordingly. Unsurprisingly, errors may be hidden which can be a real pain. Remembering to check for errors and pass them up feels annoying and unsafe.

Of course, you can use a linter to check for hidden errors, but that is more of a patch and not a real solution. In Java, exceptions are much more convenient. You don’t even have to add it to a function’s signature if it is a RuntimeException.

No generics. While convenient, generics add complexity and were considered costly to Go creators when it came down to type system and run time. When building in Go you essentially have to repeat yourself for different types or use code generation.

No annotations. While the compile-time annotations can be partially substituted with code generation, unfortunately, the runtime annotations cannot be substituted at all. This makes sense because Go is not declarative and there shouldn’t be any magic in the code.
I liked using annotations in Java though because they made the code much more elegant, simple, and minimalistic.

They would be very useful in providing some aspects or metadata for the HTTP server endpoints with swagger file generation later on. In Go, you currently have to make the swagger file manually or directly or provide special comments for the endpoints functions. This is quite a pain every time you change your API. However, annotations in Java is a kind of magic where people often do not care how they work exactly.

Dependency management in Go. I previously wrote about dependency management in Go using vgo and dep. This is a great synopsis of the issues and describes my biggest issue with Go and honestly, I’m not the only one who feels this way. The Go dependency management landscape has looked rather rocky for some time. Initially, there was no dependency management beyond “Gopgk” but the “Vendor” experiment released eventually which was later replaced with “vgo” and then further replaced with version 1.10, “go mod”. Nowadays the go.mod file descriptor can be changed both manually as well as with various Go commands, like “go get”; this, unfortunately, makes the dependencies unstable.

There is also no mirroring of the sources provided by the dependency management mechanism out of the box. It’s somewhat of a pity especially because Java has awesome declarative tools for dependency management like Maven and Gradle that also serve to build, deploy, and handle other CD/CI purposes. We effectively have to custom-build the dependency management we want using Makefiles, docker-composes, and bash scripts, which only complicates the CD/CI process and stability.

Go microservices often start in containers and end the same time locally and in a virtual Linux machine or at different platforms. Sometimes it makes the CD/CI work for development and production cycles more complicated than it needs to be.

The name of the packages includes the hosting domain name. For example:

This is really strange and especially inconvenient since you cannot replace someone’s implementation with your own implementation without changing imports over the entire projects code base.

In Java, the imports often start with the company name, like:

The difference is that in Go, the go get will go to by.spirascout.public and try to get the resource. In Java, the package and domain names do not have to correlate.

I do hope that all the problems with dependency management are temporary and will be resolved in the most effective way in the future.

Final Thoughts

One of the most interesting aspects of Go is the code naming guidelines it follows. They were based on the psychology of code readability approach (check out this article).

With Go, you can write very clear and maintainable code with separated approaches and while it is a language of many words, it still remains clear and evident.

Working at a Golang web development company has clearly shown me that Go is fast, robust, and easy to understand which makes it very good for small services and concurrent processing. For large, intricate systems, services with more complex functionality, and single-server systems, Java will hold its own among the top programming languages in the world for the time being.

While Java SE has become payable, Go is truly a child of the programming community. Actually, there are a ton of different brand JWMs, but Go’s toolset is the same one.

Bottom line: Different tasks need different tools.

If you are interested in learning more about how we do software development at Spiral Scout, are interested in joining our team, or if you just want to ask me a specific question about this article, please reach out to me at Spiral Scout using the email . I look forward to helping where I can. Best of luck with your own project and don’t forget to keep learning and trying new things!

Go vs Java infographic

Source link

r/webdev - Need help with jstl and css

Need help with jstl and css : webdev

Hey, Im working on a job search website and I have an arraylsit from my servlet class that I used jstl to print out on my jsp page, but I have some issues with the css styling.

The first pic is my current output on my website and the second pic is my coding behind it. I want something like the last pic, taken from a professional website, but I cant seem to add css to my jstl foreach loop. How would I add some css or use another way to print out my array and add css to it?

r/webdev - Need help with jstl and css
r/webdev - Need help with jstl and css
r/webdev - Need help with jstl and css

Source link

Screenshot of DevTools window for Chrome in dark mode.

Computed Values: More Than Meets the Eye

Browser DevTools are indispensable for us front end developers. In this article, we’ll take a look at the Computed tab, a small corner of the DevTools panel that shows us big things, like how relative CSS values are resolved. We’ll also see how inheritance fits into the browser’s style computation process.

Screenshot of DevTools window for Chrome in dark mode.
The “Computed” tab is generally located in the right panel of the DevTools interface, like it is shown here in Chrome.

The content in the Computed tab is important because it shows us the values that the browser is actually using on the rendered website. If an element isn’t styled how you think it should be, looking at its computed values can help you understand why.

If you’re more accustomed to using the Styles tab (called Rules in Firefox), you may wonder how it differs from the Computed tab. I mean, they both show styles that apply to an element. The answer? The Computed tab displays an alphabetized list of resolved styles that include what is declared in your stylesheet, those derived from inheritance, and the browser’s defaults.

Screenshot of Chrome DevTools in dark mode. DOM elements are on the left and the Computed Properties information is on the right.
The “Computed” tab takes a selected element (1) and displays a list of CSS properties (2) that have been rendered, allowing each one to be expanded (3) to reveal the cascade of inherited values alongside the actual computed value (4) that is currently in use.

The Styles tab, on the other hand, displays the exact rulesets of a selected element exactly as they were written. So while the Styles tab might show you something like .subhead {font-size: 75%}, the Computed tab will show you the actual font size, or what 70% currently resolves to. For example, the actual font size for the rendered text as shown above is 13.2px.

Screenshot of Chrome DevTools in dark mode. DOM elements are on the left and the Styles information is on the right.
The “Styles” tab takes a selected element (1) and displays the ruleset (2) that is explicitly declared in the stylesheet, followed by other related rulesets that are included in the cascade (3), including those from other stylesheets (4). Notice how overridden values are crossed out, indicating that another property takes precedence.

Next, let’s briefly review the concepts of inheritance and the cascade, two things that are a huge part of how the computed values in the Computed tab are arrived at.

Crash course on inheritance and the cascade

CSS stands for Cascading Style Sheets, and that first word cascading is incredibly important to understand – the way that the cascade behaves is key to understanding CSS.


The cascade is notable because it’s the “C” in CSS. It’s the mechanism used for resolving conflicts that exist between the different sources of style declarations for a document.

For example, imagine a stylesheet that defines the width of a div twice:

div {
  width: 65vw;

/* Somewhere, further down */
div {
  width: 85vw;

In this specific example, the second width wins out since it is declared last. The first width could still win with !important but that’s technically breaking the cascade by brute force. The point here is that the cascade algorithm determines what styles apply to each element and prioritizes them in a predetermined order to settle on a value.

The cascade is applied for properties that are set explicitly, whether by the browser, the web developer, or the user. Inheritance comes into the picture when the output of the cascade is empty. When this happens, the computed value of a property on an element’s parent is pulled in as its own value for that property. For example, if you specify a color for an element, all child elements will inherit that color if you don’t specify theirs.

There are four key property values related to inheritance that we should get acquainted with before we plow ahead. We’ll be using these throughout the article.


In an HTML document where the highest level of the DOM tree is the <html> element, when we use the initial keyword on an element like this…

…the text color for that element is black, even though the body element is set to green. There’s the matter of the div selector having a higher specificity, however we’re interested in why initial translated to black.

In plain terms, this keyword sets the default value of a property as specified in its definition table (in the CSS specs). In this case, black happens to be the browser’s implementation of the initial color value.

I mention near the end of the article that you can learn whether or not a property is inherited by default by checking out its page on MDN. Well, you can also find the initial value for any property this way.


For non-inherited properties, this keyword forces inheritance. In the following example, the <body> element has a solid red border. The border property isn’t inherited by default, but we can tell our div to inherit the same red border declared on the <body> element by using the inherit keyword on its border property:


unset will resolve to an inherited value if a property is inherited. Otherwise, the initial value is used. This basically means unset resets a property based on whether it is inherited or not. Here’s a demo that toggles unset to show its effect on elements with different levels of specificity.


If no CSS properties are set on an element, then does it get any styles at all? You bet. It uses the browser’s default styles.

For example, the initial value for the display property for span elements is inline, but we can specify it as block in our stylesheet. Use the button in the following demo to toggle revert on both the span element’s display and color properties:

The span properly reverts to an inline element, but wait! Did you notice that the color of the span goes to a green color instead of the browser’s default black value? That’s because revert allows for inheritance. It will go as far back as the browser’s default to set the color, but since we’ve explicitly set a green color on the <body> element, that’s what is inherited.

Finding computed values in DevTools 

This is where we start talking about the computed values in DevTools. Just as with the default values of properties, the computed value of a CSS property is determined by that property’s definition table in the CSS specifications. Here’s what that looks like for the height property.

Say we use relative lengths in our CSS, like one of 10em or 70% or 5vw. Since these are “relative” to something font-size or the viewport they’ll need to get resolved to a pixel-absolute value. For example, an element with a 10% width may compute to 100px if the viewport is 1000px wide, but some other number altogether when the viewport width changes.

Screenshot of Chrome with DevTools open in dark mode on the right. CSS-Tricks is the open site, the elements tab is open in the center, and the Computed Properties values are open on the left.
A button (1) is the current selected element in DevTools (2). The declared width of the button is 100% (3), which computes to 392px (4) when the viewport is in this condition.

These values are calculated whenever the DOM is modified in a process called computed styles calculation. This is what lets the browser know what styles to apply to each page element.

Style calculations happen in multiple steps involving several values. These are documented in the CSS Cascading and Inheritance Level 4 specification and they all impact the final value we see in the Computed tab. Let’s take a look at those next.

Values and how they’re processed

The values defined for the style calculation process include the declared value, the specified value, the cascaded value, the computed value, the used value, and the actual value. Who knew there were so many, right?

Declared values

A declared value is any property declaration applies to an element. A browser identifies these declarations based on a few criteria, including:

  • the declaration is in a stylesheet that applies to the current document
  • there was a matching selector in a style declaration
  • the style declaration contains valid syntax (i.e, valid property name and value)

Take the following HTML:

  <p>It's not denial. I'm just selective about the reality I accept.</p>

Here are declared values that apply to the font-size of the text:

main {
  font-size: 1.2em; /* this would apply if the paragraph element wasn't targeted specifically, and even then, as an inherited value, not "declared value" */

main > p {
  font-size: 1.5em; /* declared value */

Cascaded values

The list of all declared values that apply to an element are prioritized based things like these to return a single value:

  • origin of the declaration (is it from the browser, developer, or another source?)
  • whether or not the declaration is marked ‘!important’
  • how specific a rule is (e.g, span {} vs section span {})
  • order of appearance (e.g, if multiple declarations apply, the last one will be used)

In other words, the cascaded value is the “winning” declaration. And if the cascade does not result in a winning declared value, well, then there is no cascaded value.

main > p  {
  font-size: 1.2em;

main > .product-description { /* the same paragraph targeted in the previous rule */
  font-size: 1.2em; /* cascaded value based on both specificity and document order, ignoring all other considerations such as origin */

Specified values

As mentioned earlier, it is possible for the output of the cascade to be empty. However, a value still needs to be found by other means.

Now, let’s say we didn’t declare a value for a specific property on an element, but did for the parent. That’s something we often do intentionally because there’s no need to set the same value in multiple places. In this case, the inherited value for the parent is used. This is called the specified value.

In many cases, the cascaded value is also the specified value. However, it can also be an inherited value if there is no cascaded value and the property concerned is inherited, whether by default or using the inherit keyword. If the property is not inherited, then the specified value is the property’s initial value, which, as mentioned earlier, can also be set explicitly using the initial keyword.

In summary, the specified value is the value we intend to use on an element, with or without explicitly declaring it on that element. This is a little murky because the browser’s default can also become the specified value if nothing is declared in the stylesheet.

/* Browser default = 16px */

main > p {
  /* no declared value for font-size for the paragraph element and all its ancestors */

Computed values

Earlier, we discussed, briefly, how relative values needed to be resolved to their pixel-absolute equivalent. This process, as already noted, is pre-determined. For example, property definition tables have a “Computed value” field that detail how specified values, in general, are resolved.

Screenshot of the specifications section of the color property, taken from the MDN docs. The "Computed value" field is highlighted.
The specifications section of the MDN docs for the color property.

In the following example, we’re working with the em, a relative unit. Here, the final value used when rendering the element to which the property applies is not a fixed number as seen in our declared value, but something that needs to be calculated based on a few factors.

main {
  font-size: 1.2em;

main > p {
  font-size: 1.5em; /* declared value */

The font-size of the paragraph element is set to 1.5em, which is relative to the font-size value of the main element, 1.2em. If main is a direct child of the body element – and no additional font-size declarations are made above that, such as by using the :root selector – we can assume that the calculation for the paragraph’s font-size will follow this approximate course:

Browser_Default_FontSize = 16px;
Calculated_FontSize_For_Main = 1.2 * Browser_Default_FontSize; // 19.2px
Calculated_FontSize_For_Paragraph = 1.5 * Calculated_FontSize_For_Main; // 28.8px

That 28.8px is the computed value. Here’s a demo:

Open up DevTools and check out the computed font sizes in the Computed tab.

Screenshot of Chrome DevTools open to the Element view with Computed Properties open.
The declared font-size for the main element is 1.2em, which computes to 19.2px.
Screenshot of Chrome DevTools open to the Element view with Computed Properties open.
The declared font-size for the paragraph element is 1.5em, which computes to 28.8px.

Let’s say we’re using rem units instead:

html {
  font-size: 1.2em;

main {
  font-size: 1.5rem;

div {
  font-size: 1.7rem;

The computed value of a rem unit is based on the font-size of the root HTML element, so that means that the calculation changes a little bit. In this specific case, we’re using a relative unit on the HTML element as well, so the browser’s default font-size value is used to calculate the base font-size we’ll use to resolve all our rem values.

Browser_Default_FontSize = 16px
Root_FontSize = 1.2 * Browser_Default_FontSize; // 19.2px
Calculated_FontSize_For_Main = 1.5 * Root_FontSize; // 28.8px
Calculated_FontSize_For_Div = 1.7 * Root_FontSize; // 32.64px

Open up DevTools again for this demo:

The value, 16px, for Browser_Default_FontSize is commonly used by browsers, but this is subject to variation. To see your current default, select the <html> element in DevTools and check out the font-size that is shown for it. Note that if a value was set for the root element explicitly, just as in our example, you may have to toggle it off in the Rules tab. Next, toggle on the “Show all” or “Browser styles” (Firefox) checkbox in the Computed tab to see the default.

During inheritance, computed values are passed down to child elements from their parents. The computation process for this takes into account the four inheritance-controlling keywords we looked at earlier. In general, relative values become absolute (i.e. 1rem becomes 16px). This is also where relative URLs become absolute paths, and keywords such as bolder (value for the font-weight property) get resolved. You can see some more examples of this in action in the docs.

Used values

The used value is the final result after all calculations are done on the computed value. Here, all relative values are turned absolute. This used value is what will be applied (tentatively) in page layout. You might wonder why any further calculations have to happen. Wasn’t it all taken care of at the previous stage when specified values were processed to computed values?

Here’s the thing: some relative values will only be resolved to pixel-absolutes at this point. For example, a percentage-specified width might need page layout to get resolved. However, in many cases, the computed value winds up also being the used value.

Note that there are cases where a used value may not exist. According to the CSS Cascading and Inheritance Level 4 specification:

…if a property does not apply to an element, it has no used value; so, for example, the flex property has no used value on elements that aren’t flex items.

Actual values

Sometimes, a browser is unable to apply the used value straightaway and needs to make adjustments. This adjusted value is called the actual value. Think of instances where a font size needs to be tweaked based on available fonts, or when the browser can only use integer values during rendering and need to approximate non-integer values.

Inheritance in browser style computations

To recap, inheritance controls what value is applied to an element for a property that isn’t set explicitly. For inherited properties, this value is taken from whatever is computed on the parent element, and for non-inherited properties, the initial value for that property is set (the used value when the keyword initial is specified).

We talked about the existence of a “computed value” earlier, but we really need to clarify something. We discussed computed values in the sense of one type of value that takes part in the style resolution process, but “computed value” is also a general term for values computed by the browser for page styling. You’ll typically understand which kind we mean by the surrounding context.

Only computed values are accessible to an inherited property. A pixel-absolute value such as 477px, a number such as 3, or a value such as left (e.g. text-align: left) is ready for the inheritance process. A percentage value like 85% is not. When we specify relative values for properties, a final (i.e. “used”) value has to be calculated. Percentage values or other relative values will be multiplied by a reference size (font-size, for instance) or value (e.g. the width of your device viewport). So, the final value for a property can be just what was declared or it might need further processing to be used.

You may or may not have already noticed, but the values shown in the Computed tab of the browser will not necessarily be the computed values we discussed earlier (as in computed vs. specified or used values). Rather, the values shown are the same as returned by the getComputedStyle() function. This function returns a value which, depending on the property, will either be the computed value or the used value.

Now, let’s see some examples.

Color inheritance

main {
  color: blue;

/* The color will inherit anyway, but we can be explicit too: */
main > p {
  color: inherit;

The value computed for the color property on the main element will be blue. As color is inherited by default, we really didn’t need color: inherit for the paragraph child element because it would wind up being blue anyway. But it helps illustrate the point.

Color values undergo their own resolution process to become used values.

Font size inheritance

main {
  font-size: 1.2em;

main > p {
  /* No styles specified */

As we saw earlier in the section on values and how they are processed, our relative value for font-size will compute to an absolute value and then be inherited by the paragraph element, even if we don’t explicitly declare it (again, font-size is inherited by default). If we had previously set styles via a global paragraph element selector, then the paragraph may gain some extra styles by virtue of the cascade. Any property values that may be inherited will be, and some properties for which the cascade and inheritance didn’t produce a value will be set to their initial value.

Percentage-specified font size inheritance

body {
  font-size: 18px;

main {
  font-size: 80%;

main > p {
  /* No styles specified */

Similar to the previous example, the <main> element’s font-size will be absolutized in preparation for inheritance and the paragraph will inherit a font-size that is 80% of the body’s 18px value, or 14.4px.

Forced inheritance and post-layout computation

Computed values generally resolve the specified value as much as possible without layout, but as mentioned earlier, some values can only be resolved post-layout, such as percentage-specified width values. Although width isn’t an inherited property, we can force inheritance for the purpose of illustrating pre-layout and post-layout style resolution.

This is a contrived example but what we’re doing is taking an element out of the page layout by setting its display property to none. We have two divs in our markup that inherit a width, 50%, from their parent element <section>. In the Computed tab in DevTools, the computed width for the first div is absolute, having been resolved to a pixel value (243.75px for me). On the other hand, the width of the second div that was taken out of the layout using display: none is still 50%.

We’ll imagine that the specified and computed value for the parent <section> element is 50% (pre-layout) and the used value is as shown under the Computed tab – that’s 487.5px for me, post-layout. This value is halved for inheritance by the child divs (50% of the containing block).

These values have to be computed whenever the width of the browser’s viewport changes. So, percentage-specified values become percentage-computed values, which become pixel-used values.

Properties that inherit by default

How do you know if a property inherits by default or not? For each CSS property in the MDN docs, there is a specifications section that provides some extra details that include whether or not the property is inherited. Here’s what that looks like for the color property:

Screenshot of the specifications section of the color property, taken from the MDN docs. The "Inherited" field is highlighted.
The specifications section of the MDN docs for the color property.

Which properties are inherited by default and which aren’t is largely down to common sense.


Another reference option is the properties section of the W3C specs. Still another is this StackOverflow thread which may not be exhaustive at the time of writing.

Here are some examples of properties that inherit by default:

Examples of properties that do not (but which you can force to inherit with the inherit keyword):

Hopefully this gives you a solid idea of how browsers compute styles and how to reference them in DevTools. As you can see, there’s a lot that goes into a value behind the scenes. Having that context goes a long way in helping you troubleshoot your work as well as furthering your general understanding of the wonderful language we know as CSS.

Further reading

Source link

Welcome message from Expo

Build Your First React Native App

Interested in learning React Native? Let’s build your first React Native, a simple app displaying a list of countries, fetched from a REST API with a network request. This React Native tutorial is aimed at introducing React Native, giving you the basis of what you need to know before building a real React Native application. After that, we proceed to helping you build your first real React Native app. By the end of this article you will build a React Native app that can run on both iOS and Android devices.

React Native is a cross-platform development library built on top of React by Facebook, for mobile development platforms. React Native was developed in 2013 as a hackthon project inside Facebook and was later released for public use in 2015. It gained huge popularity in the developer community, and multiple tech companies adopted it as a mobile development solution because React Native apps share a single codebase for both iOS and Android and could hardly be distinguished from truly native apps. According to the React Native website:

In 2018, React Native had the 2nd highest number of contributors for any repository in GitHub. Today, React Native is supported by contributions from individuals and companies around the world, including Expo and Microsoft.

Before we go ahead and build our first React Native app, I’m going to show you the pros and cons of React Native and and more details on what it actually is.

What Is React Native?

  • React Native is a hybrid mobile development library.
  • React Native apps are written in JSX and Javascript and compiled into native code.
  • React Native apps contain 85-90% shared Javascript and JSX code

What is React Native not?

  • React Native is not a webview
  • React Native is not React
  • React Native is not PWA
  • React Native as of this writing supports web development using React Native for Web.

Why should you adopt/learn React Native?

  • Targets multiple platforms (iOS, Android, Web, TVOS) with the same codebase and effort
  • Has a large and growing community that is there to provide adequate support
  • Has native support meaning that you can customize the native code to suit your use-case/business logic
  • Requires knowledge of JavaScript. JavaScript is a language in high popular demand and learning it will pay off immensely
  • Has a feature which I personally refer to as the sweet spot: Fast Refresh (Hot Reloading)

React Native Drawbacks?

React Native has some drawbacks too, but the developers of the library are consistently trying to improve them as the community grows:

  • While the codebase is mostly shared among various platform, knowledge of native development is sometimes required in developing more advanced React Native projects
  • Despite the fact that most React Native apps look the same in appearance to native apps React Native seems to lack the smooth navigation achieved by native apps.
  • React Native developers agree that React Native style of error reporting is not the best out there but they cope with it over time.

Build Your First React Native App

Let’s build a React Native app to display a simple list of countries. The app will contain only one screen, and we are going to keep its functionality and styling to a minimum since the purpose of this tutorial is to help you set up your React Native developer environment and dip your toes into the React Native programming language.

In this React Native tutorial, we are going to use Expo in order to build your first React Native application. Expo is a powerful tool for those how are beginners in the React Native world since it lets you run and preview React Native apps on your devices easily.

1. Install Expo 

Follow the official documentation on how to install Expo. Once you’ve installed it, come back to this tutorial and follow the next steps in order to build your first React Native app.

2. Create a New React Native App

Select the ‘blank‘ project

Select ‘Y‘ to work with yarn.

Once you click Yes, Expo will work its magic and create all the necessary files for you. You can take a look at the directory structure to get an idea of what is going on in the project.

3. Run Your First React Native App

Run the following commands to start your newly created React Native app:

At this point, if you set up Expo properly at the previous steps, the new React Native project should have loaded successfully and you should be able to see the app as in the following screenshot:

Welcome message from Expo

There you have it, the very first React Native application that you’ve build. By default it says ‘Open up App.js to start working on your app‘ and I agree that it’s not the best welcome message Expo could offer but we’re going to go ahead and do as they say. Let’s open App.js file, which looks like this:

Now let me give a concise summary of what’s going on before we move on.

  • The styles variable contains various style dicts of the components
  • The Function App is a React Native Functional Component, the default one that renders what we currently see on our screen and above are import statements that import components to be used and composed to create our parent component App.

4. Add List of Countries

Let’s move on and rewrite this dummy screen with our own UI. As we mentioned before, we are going to display a list of countries. For this, we need to implement the following:

As you can see, we have updated our App.js and added a few things:

  • A Flatlist to display the list of countries
  • A dummy dataset to display to be displayed on the list
  • We updated the style object to contain the style for our text

Run your app if you haven’t started it already, and you should be seeing this:

List of countries displayed with dummy data

We now have something to work with. But the data is static and we would like a longer dynamic list, that can change and we need those changes to be reflected in the UI. So we need the UI to be “reactive” to the changes in the data model. This is the core concept of React, and therefore React Native. So we need to introduce the State concept.

A React Native component holds data in its state, and whenever the state changes, the UI is re-rendered to reflect those changes. Let’s add a state variable, named countriesData which will store the dynamic list of countries displayed on the screen.

  1. const [countriesData, setCountriesData] = useState([])

The useState is called a “hook” in React Native. According to official React documentation on hooks

A Hook is a special function that lets you “hook into” React features

We just declared a state for our app countriesData with default value as an empty array [] and a function setCountriesData to update the value of countriesData. For example, calling setCountriesData([1,2,3,]) will update the value of countriesData to [1,2,3,].

Another important hook useEffect is going to be applied in the following code snippet. Simply put, any code written inside the useEffect runs when the component is mounted.

Please don’t be scared of what’s going on. We are using the fetch API to retrieve countries data from an API endpoint and display a list of African countries. The fetch API is how you make network requests in React Native. As you can notice, we’ve used a free API endpoint, exposed on the website. This returns a JSON object, parsed in the then() clause of the fetch method. Once parsed successfully, we update the countriesData state variable with the new list of country, newly retrieved. As a result of updating the state object, the UI also gets re-rendered and we can see the countries on the screen:

List of countries with live data

5. Styling Your First React Native App

Let’s now focus on making the design of the app slightly better, since we already have the core functionality in place. We are going to focus on styling the app and our focus is on the styles dictionary.

As you can see, we’ve changed the color of the background to purple, by providing the backgroundColor attribute with ‘#483D8B’ hex code.

While the syntax is very similar to CSS, it is slightly different. But the core concepts are the same, so if you already know CSS, learning how to style React Native apps will be extremely easy. Especially if you are already familiar with flexbox layout.

Final app


We saw what are the biggest sell points for using React Native in your mobile development process, and how easy it is to create apps for both iOS and Android.

We’ve set up Expo, which is an amazing tool for beginners who are new to the React Native world. We then leveraged Expo to create our first React Native project.

After that, we learned about functional components, hooks and state. We’ve used the fetch API to retrieve data via a network request, and we styled the visual components by modifying the stylesheet.

Congratulations! You were able to build a React Native app. Now it’s time to learn more advanced concepts, in order to add more complex functionalities and develop fully functional mobile apps, that you can publish to the App Store and Google Play Store. Check out this list of the best React Native resources to learn more about React Native and dive into the next level.

Source link

r/graphic_design - Healthcare access

Healthcare access : graphic_design

Health should not be of difficult, uncomfortable access, and you have the right to receive quality medicine, in the required amount. Due to COVID outbreak, many corruption scandals have been committed regarding the trafficking of medical supplies, leaving the people with less buying choices and higher prices.

It’s sad to see that a posted created back in 2015 seems to be taking place over and over again… especially now.

More info here.

r/graphic_design - Healthcare access

“Health Access” – 2015 (By: davoxime)

Source link

Looking for roll holder for my vinyl machine

Looking for roll holder for my vinyl machine

Looking for roll holder for my vinyl machine

I am looking for a roll holder for my roland gr-640 vinyl cutter that takes 1.5 meter wide rolls, something like the picture but much bigger. does anyone know where they sell them?

submitted by /u/Chinese_Mandem

Source link